[PATCH] D76446: [ConstantRange] Use APInt::or/APInt::and for single elements.
Florian Hahn via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 19 12:33:07 PDT 2020
fhahn created this revision.
fhahn added reviewers: nikic, spatel, lebedev.ri.
Herald added a subscriber: hiraditya.
Herald added a project: LLVM.
Currently ConstantRange::binaryAnd/binaryOr results are too pessimistic
for single element constant ranges.
If both operands are single element ranges, we can use APInt's AND and
OR implementations directly.
Note that some other binary operations on constant ranges can cover the
single element cases naturally, but for OR and AND this unfortunately is
not the case.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D76446
Files:
llvm/lib/IR/ConstantRange.cpp
llvm/test/Transforms/CorrelatedValuePropagation/range.ll
Index: llvm/test/Transforms/CorrelatedValuePropagation/range.ll
===================================================================
--- llvm/test/Transforms/CorrelatedValuePropagation/range.ll
+++ llvm/test/Transforms/CorrelatedValuePropagation/range.ll
@@ -457,7 +457,7 @@
; 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
;
@@ -508,7 +508,7 @@
; 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
;
@@ -585,7 +585,7 @@
; 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
;
@@ -629,6 +629,32 @@
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(
Index: llvm/lib/IR/ConstantRange.cpp
===================================================================
--- llvm/lib/IR/ConstantRange.cpp
+++ llvm/lib/IR/ConstantRange.cpp
@@ -1194,6 +1194,10 @@
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());
@@ -1205,6 +1209,10 @@
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());
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D76446.251445.patch
Type: text/x-patch
Size: 2926 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200319/9319dced/attachment.bin>
More information about the llvm-commits
mailing list