[llvm] r300746 - [SCEV] Make SCEV or modeling more aggressive.
Eli Friedman via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 19 13:19:59 PDT 2017
Author: efriedma
Date: Wed Apr 19 15:19:58 2017
New Revision: 300746
URL: http://llvm.org/viewvc/llvm-project?rev=300746&view=rev
Log:
[SCEV] Make SCEV or modeling more aggressive.
Use haveNoCommonBitsSet to figure out whether an "or" instruction
is equivalent to addition. This handles more cases than just
checking for a constant on the RHS.
Differential Revision: https://reviews.llvm.org/D32239
Added:
llvm/trunk/test/Analysis/ScalarEvolution/or-as-add.ll
Modified:
llvm/trunk/lib/Analysis/ScalarEvolution.cpp
Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=300746&r1=300745&r2=300746&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Wed Apr 19 15:19:58 2017
@@ -5328,28 +5328,12 @@ const SCEV *ScalarEvolution::createSCEV(
break;
case Instruction::Or:
- // If the RHS of the Or is a constant, we may have something like:
- // X*4+1 which got turned into X*4|1. Handle this as an Add so loop
- // optimizations will transparently handle this case.
- //
- // In order for this transformation to be safe, the LHS must be of the
- // form X*(2^n) and the Or constant must be less than 2^n.
- if (ConstantInt *CI = dyn_cast<ConstantInt>(BO->RHS)) {
- const SCEV *LHS = getSCEV(BO->LHS);
- const APInt &CIVal = CI->getValue();
- if (GetMinTrailingZeros(LHS) >=
- (CIVal.getBitWidth() - CIVal.countLeadingZeros())) {
- // Build a plain add SCEV.
- const SCEV *S = getAddExpr(LHS, getSCEV(CI));
- // If the LHS of the add was an addrec and it has no-wrap flags,
- // transfer the no-wrap flags, since an or won't introduce a wrap.
- if (const SCEVAddRecExpr *NewAR = dyn_cast<SCEVAddRecExpr>(S)) {
- const SCEVAddRecExpr *OldAR = cast<SCEVAddRecExpr>(LHS);
- const_cast<SCEVAddRecExpr *>(NewAR)->setNoWrapFlags(
- OldAR->getNoWrapFlags());
- }
- return S;
- }
+ // Use ValueTracking to check whether this is actually an add.
+ if (haveNoCommonBitsSet(BO->LHS, BO->RHS, getDataLayout(), &AC,
+ nullptr, &DT)) {
+ // There aren't any common bits set, so the add can't wrap.
+ auto Flags = SCEV::NoWrapFlags(SCEV::FlagNUW | SCEV::FlagNSW);
+ return getAddExpr(getSCEV(BO->LHS), getSCEV(BO->RHS), Flags);
}
break;
Added: llvm/trunk/test/Analysis/ScalarEvolution/or-as-add.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/or-as-add.ll?rev=300746&view=auto
==============================================================================
--- llvm/trunk/test/Analysis/ScalarEvolution/or-as-add.ll (added)
+++ llvm/trunk/test/Analysis/ScalarEvolution/or-as-add.ll Wed Apr 19 15:19:58 2017
@@ -0,0 +1,38 @@
+; RUN: opt < %s -analyze -scalar-evolution | FileCheck %s
+
+declare void @z(i32)
+declare void @z2(i64)
+
+define void @fun(i1 %bool, i32 %x) {
+entry:
+ br label %body
+body:
+ %i = phi i32 [ 0, %entry ], [ %i.next, %body ]
+ %bottom_zero = mul i32 %i, 2
+ %a = or i32 %bottom_zero, 1
+ call void @z(i32 %a)
+ %bool_ext = zext i1 %bool to i32
+ %b = or i32 %bool_ext, %bottom_zero
+ call void @z(i32 %b)
+ %shifted = lshr i32 %x, 31
+ %c = or i32 %shifted, %bottom_zero
+ call void @z(i32 %c)
+ %i_ext = zext i32 %i to i64
+ %d = or i64 %i_ext, 4294967296
+ call void @z2(i64 %d)
+ %i.next = add i32 %i, 1
+ %cond = icmp eq i32 %i.next, 10
+ br i1 %cond, label %exit, label %body
+exit:
+ ret void
+}
+
+; CHECK: %a = or i32 %bottom_zero, 1
+; CHECK-NEXT: --> {1,+,2}<%body>
+; CHECK: %b = or i32 %bool_ext, %bottom_zero
+; CHECK-NEXT: --> {(zext i1 %bool to i32),+,2}
+; CHECK: %c = or i32 %shifted, %bottom_zero
+; CHECK-NEXT: --> {(%x /u -2147483648),+,2}<%body>
+; CHECK: %d = or i64 %i_ext, 4294967296
+; CHECK-NEXT: --> {4294967296,+,1}<nuw><nsw><%body>
+
More information about the llvm-commits
mailing list