aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2009-04-21 20:18:36 +0000
committerDan Gohman <gohman@apple.com>2009-04-21 20:18:36 +0000
commit578ccf81e5b94965e3ce8b4eadb6834e39f5f41d (patch)
treea7eb49d0dc6de05f54e2a0c9f0b7ada436ce6b5e
parent4558f481b83a3c14ad5f1077b053a748a3203059 (diff)
When turning (ashr(shl(x, n), n)) into sext(trunc(x)), the width of the
type to truncate to should be the number of bits of the value that are preserved, not the number that are clobbered with sign-extension. This fixes regressions in ldecod. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@69704 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Analysis/ScalarEvolution.cpp2
-rw-r--r--test/Analysis/ScalarEvolution/sext-inreg.ll29
2 files changed, 30 insertions, 1 deletions
diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp
index ace063a399..0aa673f355 100644
--- a/lib/Analysis/ScalarEvolution.cpp
+++ b/lib/Analysis/ScalarEvolution.cpp
@@ -2015,7 +2015,7 @@ SCEVHandle ScalarEvolutionsImpl::createSCEV(Value *V) {
if (Instruction *L = dyn_cast<Instruction>(U->getOperand(0)))
if (L->getOpcode() == Instruction::Shl &&
L->getOperand(1) == U->getOperand(1)) {
- uint64_t Amt = CI->getZExtValue();
+ uint64_t Amt = getTypeSizeInBits(U->getType()) - CI->getZExtValue();
return
SE.getSignExtendExpr(SE.getTruncateExpr(getSCEV(L->getOperand(0)),
IntegerType::get(Amt)),
diff --git a/test/Analysis/ScalarEvolution/sext-inreg.ll b/test/Analysis/ScalarEvolution/sext-inreg.ll
new file mode 100644
index 0000000000..c482fe6cf5
--- /dev/null
+++ b/test/Analysis/ScalarEvolution/sext-inreg.ll
@@ -0,0 +1,29 @@
+; RUN: llvm-as < %s | opt -analyze -scalar-evolution -disable-output \
+; RUN: | grep {signextend \{0,+,199\}<bb> to i64} | count 2
+
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
+target triple = "i386-apple-darwin9.6"
+
+define i64 @foo(i64* nocapture %x, i64 %n) nounwind {
+entry:
+ %t0 = icmp sgt i64 %n, 0 ; <i1> [#uses=1]
+ br i1 %t0, label %bb, label %return
+
+bb: ; preds = %bb, %entry
+ %i.01 = phi i64 [ 0, %entry ], [ %indvar.next, %bb ] ; <i32> [#uses=2]
+ %t1 = shl i64 %i.01, 7 ; <i32> [#uses=1]
+ %t2 = ashr i64 %t1, 7 ; <i32> [#uses=1]
+ %s1 = shl i64 %i.01, 5 ; <i32> [#uses=1]
+ %s2 = ashr i64 %s1, 5 ; <i32> [#uses=1]
+ %t3 = getelementptr i64* %x, i64 %i.01 ; <i64*> [#uses=1]
+ store i64 0, i64* %t3, align 1
+ %indvar.next = add i64 %i.01, 199 ; <i32> [#uses=2]
+ %exitcond = icmp eq i64 %indvar.next, %n ; <i1> [#uses=1]
+ br i1 %exitcond, label %return, label %bb
+
+return: ; preds = %bb, %entry
+ %p = phi i64 [ 0, %entry ], [ %t2, %bb ]
+ %q = phi i64 [ 0, %entry ], [ %s2, %bb ]
+ %v = xor i64 %p, %q
+ ret i64 %v
+}