[PATCH] D35256: [SCEV] Try harder to preserve NSW information for sext(sub) expressions

Amara Emerson via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 11 07:00:16 PDT 2017


aemerson created this revision.
Herald added a subscriber: mzolotukhin.

This helps to preserve NSW flags of sext(sub) expressions by trying to push the sign extension onto the operands of a sext instruction.


Repository:
  rL LLVM

https://reviews.llvm.org/D35256

Files:
  lib/Analysis/ScalarEvolution.cpp
  test/Analysis/ScalarEvolution/flags-from-poison.ll
  test/Transforms/LoopStrengthReduce/sext-ind-var.ll


Index: test/Transforms/LoopStrengthReduce/sext-ind-var.ll
===================================================================
--- test/Transforms/LoopStrengthReduce/sext-ind-var.ll
+++ test/Transforms/LoopStrengthReduce/sext-ind-var.ll
@@ -47,8 +47,7 @@
 ;
 define float @testsub(float* %input, i32 %offset, i32 %numIterations) {
 ; CHECK-LABEL: @testsub
-; CHECK: sub i32 0, %offset
-; CHECK: sext i32
+; CHECK: sext i32 %offset to i64
 ; CHECK: loop:
 ; CHECK-DAG: phi float*
 ; CHECK-DAG: phi i32
Index: test/Analysis/ScalarEvolution/flags-from-poison.ll
===================================================================
--- test/Analysis/ScalarEvolution/flags-from-poison.ll
+++ test/Analysis/ScalarEvolution/flags-from-poison.ll
@@ -609,7 +609,7 @@
   %index32 = sub nsw i32 %i, %sub
 
 ; CHECK: %index64 =
-; CHECK: --> {(sext i32 (-1 * %sub) to i64),+,1}<nsw>
+; CHECK: --> {(-1 * (sext i32 %sub to i64))<nsw>,+,1}<nsw
   %index64 = sext i32 %index32 to i64
 
   %ptr = getelementptr inbounds float, float* %input, i64 %index64
Index: lib/Analysis/ScalarEvolution.cpp
===================================================================
--- lib/Analysis/ScalarEvolution.cpp
+++ lib/Analysis/ScalarEvolution.cpp
@@ -5624,6 +5624,24 @@
     return getZeroExtendExpr(getSCEV(U->getOperand(0)), U->getType());
 
   case Instruction::SExt:
+    if (auto *BO = dyn_cast<BinaryOperator>(U->getOperand(0))) {
+      // The NSW flag of a subtract does not always survive the conversion to
+      // A + (-1)*B.  By pushing sign extension onto its operands we are much
+      // more likely to preserve NSW and allow later AddRec optimisations.
+      //
+      // NOTE: This is effectively duplicating this logic from getSignExtend:
+      //   sext((A + B + ...)<nsw>) --> (sext(A) + sext(B) + ...)<nsw>
+      // but by that point the NSW information has potentially been lost.
+      if (BO->getOpcode() == Instruction::Sub) {
+        SCEV::NoWrapFlags Flags = getNoWrapFlagsFromUB(BO);
+        if (maskFlags(Flags, SCEV::FlagNSW) == SCEV::FlagNSW) {
+          Type *Ty = U->getType();
+          auto *V1 = getSignExtendExpr(getSCEV(BO->getOperand(0)), Ty);
+          auto *V2 = getSignExtendExpr(getSCEV(BO->getOperand(1)), Ty);
+          return getMinusSCEV(V1, V2, SCEV::FlagNSW);
+        }
+      }
+    }
     return getSignExtendExpr(getSCEV(U->getOperand(0)), U->getType());
 
   case Instruction::BitCast:


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D35256.106019.patch
Type: text/x-patch
Size: 2423 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170711/c043c83c/attachment.bin>


More information about the llvm-commits mailing list