let merge_range loc base r1 r2 =
  match r1,r2 with
    | Fixed c1, Fixed c2 when Datatype.Int.compare c1 c2 = 0 -> r1
    | Fixed c1, Fixed c2 ->
      let min, max =
        if Datatype.Int.compare c1 c2 <= 0 then c1,c2 else c2,c1 in
      Interval (min,max)
    | Fixed c1, Interval(min,max) ->
      let min = if Datatype.Int.compare c1 min <= 0 then c1 else min in
      let max = if Datatype.Int.compare max c1 <= 0 then c1 else max in
      Interval (min,max)
    | Fixed c1, Bounded(min,_) ->
      let min = if Datatype.Int.compare c1 min <= 0 then c1 else min in
      Unbounded min
    | Fixed c1, Unbounded min ->
      let min = if Datatype.Int.compare c1 min <= 0 then c1 else min in
      Unbounded min
    | Interval(min,max), Fixed c ->
      if Datatype.Int.compare c min < 0 || Datatype.Int.compare c max > 0 then
        begin
          let min = if Datatype.Int.compare c min < 0 then c else min in
          if Cil.isLogicZero base then
            absolute_range loc min
          else Unbounded min
        end else r1
    | Interval(min1,max1), Interval(min2,max2) ->
      if Datatype.Int.compare min2 min1 < 0 
        || Datatype.Int.compare max2 max1 > 0 then
        begin
          let min = 
            if Datatype.Int.compare min2 min1 < 0 then min2 else min1
          in
          if Cil.isLogicZero base then
            absolute_range loc min
          else Unbounded min
        end else r1
    | Interval(min1,_), (Bounded(min2,_) | Unbounded min2)->
      let min = if Datatype.Int.compare min1 min2 <= 0 then min1 else min2 in
      Unbounded min
    | Bounded(min1,max1), Bounded(min2,max2)
      when Cil_datatype.Term.equal max1 max2 ->
      let min =
        if Datatype.Int.compare min2 min1 < 0 then min2 else min1
      in
      Bounded(min,max1)
    | Bounded(min1,_),
      (Fixed min2 | Interval(min2,_) | Bounded (min2,_) | Unbounded min2) ->
      let min = 
        if Datatype.Int.compare min2 min1 < 0 then min2 else min1
      in Unbounded min
    | Unbounded min1,
        (Fixed min2 | Interval(min2,_) | Bounded (min2,_) | Unbounded min2) ->
      let min =
        if Datatype.Int.compare min2 min1 < 0 then min2 else min1
      in Unbounded min