if (isEmptySet() || Other.isEmptySet())
return getEmpty();
+ // Use APInt's implementation of AND for single element ranges.
+ if (isSingleElement() && Other.isSingleElement())
+ return {*getSingleElement() & *Other.getSingleElement()};
+
// TODO: replace this with something less conservative
APInt umin = APIntOps::umin(Other.getUnsignedMax(), getUnsignedMax());
if (isEmptySet() || Other.isEmptySet())
return getEmpty();
+ // Use APInt's implementation of OR for single element ranges.
+ if (isSingleElement() && Other.isSingleElement())
+ return {*getSingleElement() | *Other.getSingleElement()};
+
// TODO: replace this with something less conservative
APInt umax = APIntOps::umax(getUnsignedMin(), Other.getUnsignedMin());
define i1 @callee_range_1(i1 %c1, i1 %c2, i1 %c3) {
; OLD_PM-LABEL: define {{[^@]+}}@callee_range_1
; OLD_PM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]])
-; OLD_PM-NEXT: [[F:%.*]] = and i1 true, true
-; OLD_PM-NEXT: ret i1 [[F]]
+; OLD_PM-NEXT: ret i1 true
;
; NEW_PM-LABEL: define {{[^@]+}}@callee_range_1
; NEW_PM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]])
-; NEW_PM-NEXT: [[F:%.*]] = and i1 true, true
-; NEW_PM-NEXT: ret i1 [[F]]
+; NEW_PM-NEXT: ret i1 true
;
; CGSCC_OLD_PM-LABEL: define {{[^@]+}}@callee_range_1
; CGSCC_OLD_PM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]])
; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK: then:
; CHECK-NEXT: [[RESULT:%.*]] = or i1 false, false
-; CHECK-NEXT: ret i1 [[RESULT]]
+; CHECK-NEXT: ret i1 false
; CHECK: else:
; CHECK-NEXT: ret i1 false
;
; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK: then:
; CHECK-NEXT: [[RESULT:%.*]] = or i1 false, false
-; CHECK-NEXT: ret i1 [[RESULT]]
+; CHECK-NEXT: ret i1 false
; CHECK: else:
; CHECK-NEXT: ret i1 false
;
; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK: then:
; CHECK-NEXT: [[RESULT:%.*]] = or i1 false, false
-; CHECK-NEXT: ret i1 [[RESULT]]
+; CHECK-NEXT: ret i1 false
; CHECK: else:
; CHECK-NEXT: ret i1 false
;
ret i1 false
}
+define i1 @test14_ugt_and(i32 %a) {
+; CHECK-LABEL: @test14_ugt_and(
+; CHECK-NEXT: [[A_OFF:%.*]] = add i32 [[A:%.*]], -8
+; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A_OFF]], 8
+; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK: then:
+; CHECK-NEXT: [[RESULT:%.*]] = and i1 false, false
+; CHECK-NEXT: ret i1 false
+; CHECK: else:
+; CHECK-NEXT: ret i1 false
+;
+ %a.off = add i32 %a, -8
+ %cmp = icmp ugt i32 %a.off, 8
+ br i1 %cmp, label %then, label %else
+
+then:
+ %dead.1 = icmp eq i32 %a, 8
+ %dead.2 = icmp eq i32 %a, 16
+ %result = and i1 %dead.1, %dead.2
+ ret i1 %result
+
+else:
+ ret i1 false
+}
+
@limit = external global i32
define i1 @test15(i32 %a) {
; CHECK-LABEL: @test15(