When emitting code for an add, don't force a SCEVUnknown wrapper around
authorDan Gohman <gohman@apple.com>
Fri, 9 Apr 2010 19:14:31 +0000 (19:14 +0000)
committerDan Gohman <gohman@apple.com>
Fri, 9 Apr 2010 19:14:31 +0000 (19:14 +0000)
a hoisted intermediate result if the intermediate result isn't an
Instruction.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@100884 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/ScalarEvolutionExpander.cpp
test/Transforms/LoopStrengthReduce/uglygep.ll [new file with mode: 0644]

index 24825bf5e565a434754a91732b68a5d174516c65..1d1339078de5d7c52e8a28ec839abe36ad2799fc 100644 (file)
@@ -705,10 +705,11 @@ Value *SCEVExpander::visitAddExpr(const SCEVAddExpr *S) {
       Sum = expandAddToGEP(NewOps.begin(), NewOps.end(), PTy, Ty, Sum);
     } else if (const PointerType *PTy = dyn_cast<PointerType>(Op->getType())) {
       // The running sum is an integer, and there's a pointer at this level.
-      // Try to form a getelementptr. Use a SCEVUnknown so that we don't
-      // re-analyze the instructions that we just emitted.
+      // Try to form a getelementptr. If the running sum is instructions,
+      // use a SCEVUnknown to avoid re-analyzing them.
       SmallVector<const SCEV *, 4> NewOps;
-      NewOps.push_back(SE.getUnknown(Sum));
+      NewOps.push_back(isa<Instruction>(Sum) ? SE.getUnknown(Sum) :
+                                               SE.getSCEV(Sum));
       for (++I; I != E && I->first == CurLoop; ++I)
         NewOps.push_back(I->second);
       Sum = expandAddToGEP(NewOps.begin(), NewOps.end(), PTy, Ty, expand(Op));
diff --git a/test/Transforms/LoopStrengthReduce/uglygep.ll b/test/Transforms/LoopStrengthReduce/uglygep.ll
new file mode 100644 (file)
index 0000000..e72364f
--- /dev/null
@@ -0,0 +1,37 @@
+; RUN: opt < %s -loop-reduce -S | not grep uglygep
+
+; LSR shouldn't consider %t8 to be an interesting user of %t6, and it
+; should be able to form pretty GEPs.
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @Z4() nounwind {
+bb:
+  br label %bb3
+
+bb1:                                              ; preds = %bb3
+  br i1 undef, label %bb10, label %bb2
+
+bb2:                                              ; preds = %bb1
+  %t = add i64 %t4, 1                         ; <i64> [#uses=1]
+  br label %bb3
+
+bb3:                                              ; preds = %bb2, %bb
+  %t4 = phi i64 [ %t, %bb2 ], [ 0, %bb ]      ; <i64> [#uses=3]
+  br label %bb1
+
+bb10:                                             ; preds = %bb9
+  %t7 = icmp eq i64 %t4, 0                    ; <i1> [#uses=1]
+  %t3 = add i64 %t4, 16                     ; <i64> [#uses=1]
+  br label %bb14
+
+bb14:                                             ; preds = %bb14, %bb10
+  %t2 = getelementptr inbounds i8* undef, i64 %t4 ; <i8*> [#uses=1]
+  store i8 undef, i8* %t2
+  %t6 = load float** undef
+  %t8 = bitcast float* %t6 to i8*              ; <i8*> [#uses=1]
+  %t9 = getelementptr inbounds i8* %t8, i64 %t3 ; <i8*> [#uses=1]
+  store i8 undef, i8* %t9
+  br label %bb14
+}