[PATCH] D34207: [IndVarSimplify] Add AShr exact flags using induction variables ranges.

Dave Green via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 14 08:45:34 PDT 2017


dmgreen created this revision.
Herald added a subscriber: sanjoy.

This is an attempt to fix a regression we saw in benchmarks of FFT like code after computeKnownBitsFromShiftOperator was made more strict with respect to possibly shifting past the bitwidth. It adds exact flags to AShr flags where we can statically prove it is valid using the range of induction variables. This allows further optimisations to remove extra loads.


https://reviews.llvm.org/D34207

Files:
  lib/Transforms/Utils/SimplifyIndVar.cpp
  test/Transforms/IndVarSimplify/strengthen-overflow.ll


Index: test/Transforms/IndVarSimplify/strengthen-overflow.ll
===================================================================
--- test/Transforms/IndVarSimplify/strengthen-overflow.ll
+++ test/Transforms/IndVarSimplify/strengthen-overflow.ll
@@ -104,5 +104,37 @@
   ret i32 42
 }
 
+define hidden void @test.shl() {
+; CHECK-LABEL: @test.shl
+entry:
+  br label %for.body
+
+for.body:
+; CHECK-LABEL: for.body
+  %k.021 = phi i32 [ 1, %entry ], [ %inc, %for.body ]
+  %shl = shl i32 1, %k.021
+  %shr = ashr i32 %shl, 1
+; CHECK: %shr = ashr exact i32 %shl, 1
+  %div = sdiv i32 %shr, 2
+  %add = add nsw i32 %div, %shr
+  %arrayidx = getelementptr inbounds [16 x i32], [16 x i32]* @Data, i32 0, i32 %add
+  %arrayidx1 = getelementptr inbounds [16 x i32], [16 x i32]* @Data, i32 0, i32 %div
+  %0 = load i32, i32* %arrayidx, align 4
+  %1 = load i32, i32* %arrayidx1, align 4
+  %sub = sub nsw i32 %1, %0
+  store i32 %sub, i32* %arrayidx, align 4
+  %2 = load i32, i32* %arrayidx1, align 4
+  %add4 = add nsw i32 %2, %0
+  store i32 %add4, i32* %arrayidx1, align 4
+  %inc = add nuw nsw i32 %k.021, 1
+  %exitcond = icmp eq i32 %inc, 9
+  br i1 %exitcond, label %for.end, label %for.body
+
+for.end:
+  ret void
+}
+
+ at Data = hidden local_unnamed_addr global [16 x i32] zeroinitializer, align 4
+
 !0 = !{i32 0, i32 2}
 !1 = !{i32 0, i32 42}
Index: lib/Transforms/Utils/SimplifyIndVar.cpp
===================================================================
--- lib/Transforms/Utils/SimplifyIndVar.cpp
+++ lib/Transforms/Utils/SimplifyIndVar.cpp
@@ -521,9 +521,36 @@
 }
 
 /// Annotate BO with nsw / nuw if it provably does not signed-overflow /
-/// unsigned-overflow.  Returns true if anything changed, false otherwise.
+/// unsigned-overflow.  Also check for shifts that can be marked as exact.
+/// Returns true if anything changed, false otherwise.
 bool SimplifyIndvar::strengthenOverflowingOperation(BinaryOperator *BO,
                                                     Value *IVOperand) {
+  // match (X << IVOperand) >> C, marking the AShr as exact using the
+  // information from the IV's range
+  if(BO->getOpcode() == Instruction::Shl) {
+    bool Changed = false;
+    for(auto* user : BO->users()) {
+      BinaryOperator* AShr = dyn_cast<BinaryOperator>(user);
+      if(!AShr || AShr->getOpcode() != Instruction::AShr ||
+          AShr->getOperand(0) != BO || AShr->isExact())
+        continue;
+
+      ConstantRange IVRange = SE->getUnsignedRange(SE->getSCEV(IVOperand));
+
+      Value* ShlOp1 = BO->getOperand(0);
+      if(ShlOp1 == IVOperand || !BO->getType()->isIntegerTy() ||
+          IVRange.getUpper().uge(BO->getType()->getPrimitiveSizeInBits()))
+        continue;
+
+      ConstantInt* AShrOp2 = dyn_cast<ConstantInt>(AShr->getOperand(1));
+      if(!AShrOp2 || IVRange.getLower().ult(AShrOp2->getValue()))
+        continue;
+
+      AShr->setIsExact(true);
+      Changed = true;
+    }
+    return Changed;
+  }
 
   // Fastpath: we don't have any work to do if `BO` is `nuw` and `nsw`.
   if (BO->hasNoUnsignedWrap() && BO->hasNoSignedWrap())


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D34207.102558.patch
Type: text/x-patch
Size: 3087 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170614/d7d661f5/attachment.bin>


More information about the llvm-commits mailing list