[PATCH] D17177: [LVI] Exploit nsw/nuw when computing constant ranges
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Fri Feb 12 11:09:40 PST 2016
This revision was automatically updated to reflect the committed changes.
Closed by commit rL260705: [LVI] Exploit nsw/nuw when computing constant ranges (authored by reames).
Changed prior to commit:
http://reviews.llvm.org/D17177?vs=47748&id=47821#toc
Repository:
rL LLVM
http://reviews.llvm.org/D17177
Files:
llvm/trunk/lib/Analysis/LazyValueInfo.cpp
llvm/trunk/test/Transforms/CorrelatedValuePropagation/basic.ll
Index: llvm/trunk/test/Transforms/CorrelatedValuePropagation/basic.ll
===================================================================
--- llvm/trunk/test/Transforms/CorrelatedValuePropagation/basic.ll
+++ llvm/trunk/test/Transforms/CorrelatedValuePropagation/basic.ll
@@ -199,3 +199,58 @@
next:
ret void
}
+
+; Can we use nsw in LVI to prove lack of overflow?
+define i1 @add_nsw(i32 %s) {
+; CHECK-LABEL: @add_nsw(
+entry:
+ %cmp = icmp sgt i32 %s, 0
+ br i1 %cmp, label %positive, label %out
+
+positive:
+ %add = add nsw i32 %s, 1
+ %res = icmp sgt i32 %add, 0
+ br label %next
+next:
+; CHECK: next:
+; CHECK: ret i1 true
+ ret i1 %res
+out:
+ ret i1 false
+}
+
+define i1 @add_nsw2(i32 %s) {
+; CHECK-LABEL: @add_nsw2(
+entry:
+ %cmp = icmp sge i32 %s, 0
+ br i1 %cmp, label %positive, label %out
+
+positive:
+ %add = add nsw i32 %s, 1
+ %res = icmp ne i32 %add, 0
+ br label %next
+next:
+; CHECK: next:
+; CHECK: ret i1 true
+ ret i1 %res
+out:
+ ret i1 false
+}
+
+define i1 @add_nuw(i32 %s) {
+; CHECK-LABEL: @add_nuw(
+entry:
+ %cmp = icmp ult i32 %s, 400
+ br i1 %cmp, label %positive, label %out
+
+positive:
+ %add = add nsw i32 %s, 1
+ %res = icmp ne i32 %add, -100
+ br label %next
+next:
+; CHECK: next:
+; CHECK: ret i1 true
+ ret i1 %res
+out:
+ ret i1 false
+}
Index: llvm/trunk/lib/Analysis/LazyValueInfo.cpp
===================================================================
--- llvm/trunk/lib/Analysis/LazyValueInfo.cpp
+++ llvm/trunk/lib/Analysis/LazyValueInfo.cpp
@@ -961,6 +961,27 @@
if (isa<BinaryOperator>(BBI)) {
if (ConstantInt *RHS = dyn_cast<ConstantInt>(BBI->getOperand(1))) {
RHSRange = ConstantRange(RHS->getValue());
+
+ // Try to use information about wrap flags to refine the range LHS can
+ // legally have. This is a slightly weird way to implement forward
+ // propagation over overflowing instructions, but it seems to be the only
+ // clean one we have. NOTE: Because we may have speculated the
+ // instruction, we can't constrain other uses of LHS even if they would
+ // seem to be equivelent control dependent with this op.
+ if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(BBI)) {
+ unsigned WrapKind = 0;
+ if (OBO->hasNoSignedWrap())
+ WrapKind |= OverflowingBinaryOperator::NoSignedWrap;
+ if (OBO->hasNoUnsignedWrap())
+ WrapKind |= OverflowingBinaryOperator::NoUnsignedWrap;
+
+ if (WrapKind) {
+ auto OpCode = static_cast<Instruction::BinaryOps>(BBI->getOpcode());
+ auto NoWrapCR =
+ ConstantRange::makeNoWrapRegion(OpCode, RHS->getValue(), WrapKind);
+ LHSRange = LHSRange.intersectWith(NoWrapCR);
+ }
+ }
} else {
BBLV.markOverdefined();
return true;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D17177.47821.patch
Type: text/x-patch
Size: 2810 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160212/3eac7a25/attachment.bin>
More information about the llvm-commits
mailing list