Teach getZeroExtendExpr and getSignExtendExpr to use trip-count
information to simplify [sz]ext({a,+,b}) to {zext(a),+,[zs]ext(b)},
as appropriate.

These functions and the trip count code each call into the other, so
this requires careful handling to avoid infinite recursion. During
the initial trip count computation, conservative SCEVs are used,
which are subsequently discarded once the trip count is actually
known.

Among other benefits, this change lets LSR automatically eliminate
some unnecessary zext-inreg and sext-inreg operation where the
operand is an induction variable.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@70241 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/CodeGen/X86/masked-iv-safe.ll b/test/CodeGen/X86/masked-iv-safe.ll
new file mode 100644
index 0000000..2ba3f83
--- /dev/null
+++ b/test/CodeGen/X86/masked-iv-safe.ll
@@ -0,0 +1,244 @@
+; RUN: llvm-as < %s | llc -march=x86-64 > %t
+; RUN: not grep and %t
+; RUN: not grep movz %t
+; RUN: not grep sar %t
+; RUN: not grep shl %t
+; RUN: grep add %t | count 6
+; RUN: grep inc %t | count 4
+; RUN: grep dec %t | count 2
+; RUN: grep lea %t | count 2
+
+; Optimize away zext-inreg and sext-inreg on the loop induction
+; variable using trip-count information.
+
+define void @count_up(double* %d, i64 %n) nounwind {
+entry:
+	br label %loop
+
+loop:
+	%indvar = phi i64 [ 0, %entry ], [ %indvar.next, %loop ]
+	%indvar.i8 = and i64 %indvar, 255
+	%t0 = getelementptr double* %d, i64 %indvar.i8
+	%t1 = load double* %t0
+	%t2 = mul double %t1, 0.1
+	store double %t2, double* %t0
+	%indvar.i24 = and i64 %indvar, 16777215
+	%t3 = getelementptr double* %d, i64 %indvar.i24
+	%t4 = load double* %t3
+	%t5 = mul double %t4, 2.3
+	store double %t5, double* %t3
+	%t6 = getelementptr double* %d, i64 %indvar
+	%t7 = load double* %t6
+	%t8 = mul double %t7, 4.5
+	store double %t8, double* %t6
+	%indvar.next = add i64 %indvar, 1
+	%exitcond = icmp eq i64 %indvar.next, 10
+	br i1 %exitcond, label %return, label %loop
+
+return:
+	ret void
+}
+
+define void @count_down(double* %d, i64 %n) nounwind {
+entry:
+	br label %loop
+
+loop:
+	%indvar = phi i64 [ 10, %entry ], [ %indvar.next, %loop ]
+	%indvar.i8 = and i64 %indvar, 255
+	%t0 = getelementptr double* %d, i64 %indvar.i8
+	%t1 = load double* %t0
+	%t2 = mul double %t1, 0.1
+	store double %t2, double* %t0
+	%indvar.i24 = and i64 %indvar, 16777215
+	%t3 = getelementptr double* %d, i64 %indvar.i24
+	%t4 = load double* %t3
+	%t5 = mul double %t4, 2.3
+	store double %t5, double* %t3
+	%t6 = getelementptr double* %d, i64 %indvar
+	%t7 = load double* %t6
+	%t8 = mul double %t7, 4.5
+	store double %t8, double* %t6
+	%indvar.next = sub i64 %indvar, 1
+	%exitcond = icmp eq i64 %indvar.next, 0
+	br i1 %exitcond, label %return, label %loop
+
+return:
+	ret void
+}
+
+define void @count_up_signed(double* %d, i64 %n) nounwind {
+entry:
+	br label %loop
+
+loop:
+	%indvar = phi i64 [ 0, %entry ], [ %indvar.next, %loop ]
+        %s0 = shl i64 %indvar, 8
+	%indvar.i8 = ashr i64 %s0, 8
+	%t0 = getelementptr double* %d, i64 %indvar.i8
+	%t1 = load double* %t0
+	%t2 = mul double %t1, 0.1
+	store double %t2, double* %t0
+	%s1 = shl i64 %indvar, 24
+	%indvar.i24 = ashr i64 %s1, 24
+	%t3 = getelementptr double* %d, i64 %indvar.i24
+	%t4 = load double* %t3
+	%t5 = mul double %t4, 2.3
+	store double %t5, double* %t3
+	%t6 = getelementptr double* %d, i64 %indvar
+	%t7 = load double* %t6
+	%t8 = mul double %t7, 4.5
+	store double %t8, double* %t6
+	%indvar.next = add i64 %indvar, 1
+	%exitcond = icmp eq i64 %indvar.next, 10
+	br i1 %exitcond, label %return, label %loop
+
+return:
+	ret void
+}
+
+define void @count_down_signed(double* %d, i64 %n) nounwind {
+entry:
+	br label %loop
+
+loop:
+	%indvar = phi i64 [ 10, %entry ], [ %indvar.next, %loop ]
+        %s0 = shl i64 %indvar, 8
+	%indvar.i8 = ashr i64 %s0, 8
+	%t0 = getelementptr double* %d, i64 %indvar.i8
+	%t1 = load double* %t0
+	%t2 = mul double %t1, 0.1
+	store double %t2, double* %t0
+	%s1 = shl i64 %indvar, 24
+	%indvar.i24 = ashr i64 %s1, 24
+	%t3 = getelementptr double* %d, i64 %indvar.i24
+	%t4 = load double* %t3
+	%t5 = mul double %t4, 2.3
+	store double %t5, double* %t3
+	%t6 = getelementptr double* %d, i64 %indvar
+	%t7 = load double* %t6
+	%t8 = mul double %t7, 4.5
+	store double %t8, double* %t6
+	%indvar.next = sub i64 %indvar, 1
+	%exitcond = icmp eq i64 %indvar.next, 0
+	br i1 %exitcond, label %return, label %loop
+
+return:
+	ret void
+}
+
+define void @another_count_up(double* %d, i64 %n) nounwind {
+entry:
+	br label %loop
+
+loop:
+	%indvar = phi i64 [ 18446744073709551615, %entry ], [ %indvar.next, %loop ]
+	%indvar.i8 = and i64 %indvar, 255
+	%t0 = getelementptr double* %d, i64 %indvar.i8
+	%t1 = load double* %t0
+	%t2 = mul double %t1, 0.1
+	store double %t2, double* %t0
+	%indvar.i24 = and i64 %indvar, 16777215
+	%t3 = getelementptr double* %d, i64 %indvar.i24
+	%t4 = load double* %t3
+	%t5 = mul double %t4, 2.3
+	store double %t5, double* %t3
+	%t6 = getelementptr double* %d, i64 %indvar
+	%t7 = load double* %t6
+	%t8 = mul double %t7, 4.5
+	store double %t8, double* %t6
+	%indvar.next = add i64 %indvar, 1
+	%exitcond = icmp eq i64 %indvar.next, 0
+	br i1 %exitcond, label %return, label %loop
+
+return:
+	ret void
+}
+
+define void @another_count_down(double* %d, i64 %n) nounwind {
+entry:
+	br label %loop
+
+loop:
+	%indvar = phi i64 [ 0, %entry ], [ %indvar.next, %loop ]
+	%indvar.i8 = and i64 %indvar, 255
+	%t0 = getelementptr double* %d, i64 %indvar.i8
+	%t1 = load double* %t0
+	%t2 = mul double %t1, 0.1
+	store double %t2, double* %t0
+	%indvar.i24 = and i64 %indvar, 16777215
+	%t3 = getelementptr double* %d, i64 %indvar.i24
+	%t4 = load double* %t3
+	%t5 = mul double %t4, 2.3
+	store double %t5, double* %t3
+	%t6 = getelementptr double* %d, i64 %indvar
+	%t7 = load double* %t6
+	%t8 = mul double %t7, 4.5
+	store double %t8, double* %t6
+	%indvar.next = sub i64 %indvar, 1
+	%exitcond = icmp eq i64 %indvar.next, 18446744073709551615
+	br i1 %exitcond, label %return, label %loop
+
+return:
+	ret void
+}
+
+define void @another_count_up_signed(double* %d, i64 %n) nounwind {
+entry:
+	br label %loop
+
+loop:
+	%indvar = phi i64 [ 18446744073709551615, %entry ], [ %indvar.next, %loop ]
+        %s0 = shl i64 %indvar, 8
+	%indvar.i8 = ashr i64 %s0, 8
+	%t0 = getelementptr double* %d, i64 %indvar.i8
+	%t1 = load double* %t0
+	%t2 = mul double %t1, 0.1
+	store double %t2, double* %t0
+	%s1 = shl i64 %indvar, 24
+	%indvar.i24 = ashr i64 %s1, 24
+	%t3 = getelementptr double* %d, i64 %indvar.i24
+	%t4 = load double* %t3
+	%t5 = mul double %t4, 2.3
+	store double %t5, double* %t3
+	%t6 = getelementptr double* %d, i64 %indvar
+	%t7 = load double* %t6
+	%t8 = mul double %t7, 4.5
+	store double %t8, double* %t6
+	%indvar.next = add i64 %indvar, 1
+	%exitcond = icmp eq i64 %indvar.next, 0
+	br i1 %exitcond, label %return, label %loop
+
+return:
+	ret void
+}
+
+define void @another_count_down_signed(double* %d, i64 %n) nounwind {
+entry:
+	br label %loop
+
+loop:
+	%indvar = phi i64 [ 0, %entry ], [ %indvar.next, %loop ]
+        %s0 = shl i64 %indvar, 8
+	%indvar.i8 = ashr i64 %s0, 8
+	%t0 = getelementptr double* %d, i64 %indvar.i8
+	%t1 = load double* %t0
+	%t2 = mul double %t1, 0.1
+	store double %t2, double* %t0
+	%s1 = shl i64 %indvar, 24
+	%indvar.i24 = ashr i64 %s1, 24
+	%t3 = getelementptr double* %d, i64 %indvar.i24
+	%t4 = load double* %t3
+	%t5 = mul double %t4, 2.3
+	store double %t5, double* %t3
+	%t6 = getelementptr double* %d, i64 %indvar
+	%t7 = load double* %t6
+	%t8 = mul double %t7, 4.5
+	store double %t8, double* %t6
+	%indvar.next = sub i64 %indvar, 1
+	%exitcond = icmp eq i64 %indvar.next, 18446744073709551615
+	br i1 %exitcond, label %return, label %loop
+
+return:
+	ret void
+}
diff --git a/test/CodeGen/X86/masked-iv-unsafe.ll b/test/CodeGen/X86/masked-iv-unsafe.ll
new file mode 100644
index 0000000..7ccfe85
--- /dev/null
+++ b/test/CodeGen/X86/masked-iv-unsafe.ll
@@ -0,0 +1,386 @@
+; RUN: llvm-as < %s | llc -march=x86-64 > %t
+; RUN: grep and %t | count 6
+; RUN: grep movzb %t | count 6
+; RUN: grep sar %t | count 12
+
+; Don't optimize away zext-inreg and sext-inreg on the loop induction
+; variable, because it isn't safe to do so in these cases.
+
+define void @count_up(double* %d, i64 %n) nounwind {
+entry:
+	br label %loop
+
+loop:
+	%indvar = phi i64 [ 10, %entry ], [ %indvar.next, %loop ]
+	%indvar.i8 = and i64 %indvar, 255
+	%t0 = getelementptr double* %d, i64 %indvar.i8
+	%t1 = load double* %t0
+	%t2 = mul double %t1, 0.1
+	store double %t2, double* %t0
+	%indvar.i24 = and i64 %indvar, 16777215
+	%t3 = getelementptr double* %d, i64 %indvar.i24
+	%t4 = load double* %t3
+	%t5 = mul double %t4, 2.3
+	store double %t5, double* %t3
+	%t6 = getelementptr double* %d, i64 %indvar
+	%t7 = load double* %t6
+	%t8 = mul double %t7, 4.5
+	store double %t8, double* %t6
+	%indvar.next = add i64 %indvar, 1
+	%exitcond = icmp eq i64 %indvar.next, 0
+	br i1 %exitcond, label %return, label %loop
+
+return:
+	ret void
+}
+
+define void @count_down(double* %d, i64 %n) nounwind {
+entry:
+	br label %loop
+
+loop:
+	%indvar = phi i64 [ 10, %entry ], [ %indvar.next, %loop ]
+	%indvar.i8 = and i64 %indvar, 255
+	%t0 = getelementptr double* %d, i64 %indvar.i8
+	%t1 = load double* %t0
+	%t2 = mul double %t1, 0.1
+	store double %t2, double* %t0
+	%indvar.i24 = and i64 %indvar, 16777215
+	%t3 = getelementptr double* %d, i64 %indvar.i24
+	%t4 = load double* %t3
+	%t5 = mul double %t4, 2.3
+	store double %t5, double* %t3
+	%t6 = getelementptr double* %d, i64 %indvar
+	%t7 = load double* %t6
+	%t8 = mul double %t7, 4.5
+	store double %t8, double* %t6
+	%indvar.next = sub i64 %indvar, 1
+	%exitcond = icmp eq i64 %indvar.next, 20
+	br i1 %exitcond, label %return, label %loop
+
+return:
+	ret void
+}
+
+define void @count_up_signed(double* %d, i64 %n) nounwind {
+entry:
+	br label %loop
+
+loop:
+	%indvar = phi i64 [ 10, %entry ], [ %indvar.next, %loop ]
+        %s0 = shl i64 %indvar, 8
+	%indvar.i8 = ashr i64 %s0, 8
+	%t0 = getelementptr double* %d, i64 %indvar.i8
+	%t1 = load double* %t0
+	%t2 = mul double %t1, 0.1
+	store double %t2, double* %t0
+	%s1 = shl i64 %indvar, 24
+	%indvar.i24 = ashr i64 %s1, 24
+	%t3 = getelementptr double* %d, i64 %indvar.i24
+	%t4 = load double* %t3
+	%t5 = mul double %t4, 2.3
+	store double %t5, double* %t3
+	%t6 = getelementptr double* %d, i64 %indvar
+	%t7 = load double* %t6
+	%t8 = mul double %t7, 4.5
+	store double %t8, double* %t6
+	%indvar.next = add i64 %indvar, 1
+	%exitcond = icmp eq i64 %indvar.next, 0
+	br i1 %exitcond, label %return, label %loop
+
+return:
+	ret void
+}
+
+define void @count_down_signed(double* %d, i64 %n) nounwind {
+entry:
+	br label %loop
+
+loop:
+	%indvar = phi i64 [ 10, %entry ], [ %indvar.next, %loop ]
+        %s0 = shl i64 %indvar, 8
+	%indvar.i8 = ashr i64 %s0, 8
+	%t0 = getelementptr double* %d, i64 %indvar.i8
+	%t1 = load double* %t0
+	%t2 = mul double %t1, 0.1
+	store double %t2, double* %t0
+	%s1 = shl i64 %indvar, 24
+	%indvar.i24 = ashr i64 %s1, 24
+	%t3 = getelementptr double* %d, i64 %indvar.i24
+	%t4 = load double* %t3
+	%t5 = mul double %t4, 2.3
+	store double %t5, double* %t3
+	%t6 = getelementptr double* %d, i64 %indvar
+	%t7 = load double* %t6
+	%t8 = mul double %t7, 4.5
+	store double %t8, double* %t6
+	%indvar.next = sub i64 %indvar, 1
+	%exitcond = icmp eq i64 %indvar.next, 20
+	br i1 %exitcond, label %return, label %loop
+
+return:
+	ret void
+}
+
+define void @another_count_up(double* %d, i64 %n) nounwind {
+entry:
+        br label %loop
+
+loop:
+        %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %loop ]
+        %indvar.i8 = and i64 %indvar, 255
+        %t0 = getelementptr double* %d, i64 %indvar.i8
+        %t1 = load double* %t0
+        %t2 = mul double %t1, 0.1
+        store double %t2, double* %t0
+        %indvar.i24 = and i64 %indvar, 16777215
+        %t3 = getelementptr double* %d, i64 %indvar.i24
+        %t4 = load double* %t3
+        %t5 = mul double %t4, 2.3
+        store double %t5, double* %t3
+        %t6 = getelementptr double* %d, i64 %indvar
+        %t7 = load double* %t6
+        %t8 = mul double %t7, 4.5
+        store double %t8, double* %t6
+        %indvar.next = add i64 %indvar, 1
+        %exitcond = icmp eq i64 %indvar.next, %n
+        br i1 %exitcond, label %return, label %loop
+
+return:
+        ret void
+}
+
+define void @another_count_down(double* %d, i64 %n) nounwind {
+entry:
+        br label %loop
+
+loop:
+        %indvar = phi i64 [ %n, %entry ], [ %indvar.next, %loop ]
+        %indvar.i8 = and i64 %indvar, 255
+        %t0 = getelementptr double* %d, i64 %indvar.i8
+        %t1 = load double* %t0
+        %t2 = mul double %t1, 0.1
+        store double %t2, double* %t0
+        %indvar.i24 = and i64 %indvar, 16777215
+        %t3 = getelementptr double* %d, i64 %indvar.i24
+        %t4 = load double* %t3
+        %t5 = mul double %t4, 2.3
+        store double %t5, double* %t3
+        %t6 = getelementptr double* %d, i64 %indvar
+        %t7 = load double* %t6
+        %t8 = mul double %t7, 4.5
+        store double %t8, double* %t6
+        %indvar.next = sub i64 %indvar, 1
+        %exitcond = icmp eq i64 %indvar.next, 10
+        br i1 %exitcond, label %return, label %loop
+
+return:
+        ret void
+}
+
+define void @another_count_up_signed(double* %d, i64 %n) nounwind {
+entry:
+        br label %loop
+
+loop:
+        %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %loop ]
+        %s0 = shl i64 %indvar, 8
+        %indvar.i8 = ashr i64 %s0, 8
+        %t0 = getelementptr double* %d, i64 %indvar.i8
+        %t1 = load double* %t0
+        %t2 = mul double %t1, 0.1
+        store double %t2, double* %t0
+        %s1 = shl i64 %indvar, 24
+        %indvar.i24 = ashr i64 %s1, 24
+        %t3 = getelementptr double* %d, i64 %indvar.i24
+        %t4 = load double* %t3
+        %t5 = mul double %t4, 2.3
+        store double %t5, double* %t3
+        %t6 = getelementptr double* %d, i64 %indvar
+        %t7 = load double* %t6
+        %t8 = mul double %t7, 4.5
+        store double %t8, double* %t6
+        %indvar.next = add i64 %indvar, 1
+        %exitcond = icmp eq i64 %indvar.next, %n
+        br i1 %exitcond, label %return, label %loop
+
+return:
+        ret void
+}
+
+define void @another_count_down_signed(double* %d, i64 %n) nounwind {
+entry:
+        br label %loop
+
+loop:
+        %indvar = phi i64 [ %n, %entry ], [ %indvar.next, %loop ]
+        %s0 = shl i64 %indvar, 8
+        %indvar.i8 = ashr i64 %s0, 8
+        %t0 = getelementptr double* %d, i64 %indvar.i8
+        %t1 = load double* %t0
+        %t2 = mul double %t1, 0.1
+        store double %t2, double* %t0
+        %s1 = shl i64 %indvar, 24
+        %indvar.i24 = ashr i64 %s1, 24
+        %t3 = getelementptr double* %d, i64 %indvar.i24
+        %t4 = load double* %t3
+        %t5 = mul double %t4, 2.3
+        store double %t5, double* %t3
+        %t6 = getelementptr double* %d, i64 %indvar
+        %t7 = load double* %t6
+        %t8 = mul double %t7, 4.5
+        store double %t8, double* %t6
+        %indvar.next = sub i64 %indvar, 1
+        %exitcond = icmp eq i64 %indvar.next, 10
+        br i1 %exitcond, label %return, label %loop
+
+return:
+        ret void
+}
+
+define void @yet_another_count_down(double* %d, i64 %n) nounwind {
+entry:
+	br label %loop
+
+loop:
+	%indvar = phi i64 [ 0, %entry ], [ %indvar.next, %loop ]
+	%indvar.i8 = and i64 %indvar, 255
+	%t0 = getelementptr double* %d, i64 %indvar.i8
+	%t1 = load double* %t0
+	%t2 = mul double %t1, 0.1
+	store double %t2, double* %t0
+	%indvar.i24 = and i64 %indvar, 16777215
+	%t3 = getelementptr double* %d, i64 %indvar.i24
+	%t4 = load double* %t3
+	%t5 = mul double %t4, 2.3
+	store double %t5, double* %t3
+	%t6 = getelementptr double* %d, i64 %indvar
+	%t7 = load double* %t6
+	%t8 = mul double %t7, 4.5
+	store double %t8, double* %t6
+	%indvar.next = sub i64 %indvar, 1
+	%exitcond = icmp eq i64 %indvar.next, 18446744073709551615
+	br i1 %exitcond, label %return, label %loop
+
+return:
+	ret void
+}
+
+define void @yet_another_count_up(double* %d, i64 %n) nounwind {
+entry:
+        br label %loop
+
+loop:
+        %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %loop ]
+        %indvar.i8 = and i64 %indvar, 255
+        %t0 = getelementptr double* %d, i64 %indvar.i8
+        %t1 = load double* %t0
+        %t2 = mul double %t1, 0.1
+        store double %t2, double* %t0
+        %indvar.i24 = and i64 %indvar, 16777215
+        %t3 = getelementptr double* %d, i64 %indvar.i24
+        %t4 = load double* %t3
+        %t5 = mul double %t4, 2.3
+        store double %t5, double* %t3
+        %t6 = getelementptr double* %d, i64 %indvar
+        %t7 = load double* %t6
+        %t8 = mul double %t7, 4.5
+        store double %t8, double* %t6
+        %indvar.next = add i64 %indvar, 3
+        %exitcond = icmp eq i64 %indvar.next, 10
+        br i1 %exitcond, label %return, label %loop
+
+return:
+        ret void
+}
+
+define void @still_another_count_down(double* %d, i64 %n) nounwind {
+entry:
+        br label %loop
+
+loop:
+        %indvar = phi i64 [ 10, %entry ], [ %indvar.next, %loop ]
+        %indvar.i8 = and i64 %indvar, 255
+        %t0 = getelementptr double* %d, i64 %indvar.i8
+        %t1 = load double* %t0
+        %t2 = mul double %t1, 0.1
+        store double %t2, double* %t0
+        %indvar.i24 = and i64 %indvar, 16777215
+        %t3 = getelementptr double* %d, i64 %indvar.i24
+        %t4 = load double* %t3
+        %t5 = mul double %t4, 2.3
+        store double %t5, double* %t3
+        %t6 = getelementptr double* %d, i64 %indvar
+        %t7 = load double* %t6
+        %t8 = mul double %t7, 4.5
+        store double %t8, double* %t6
+        %indvar.next = sub i64 %indvar, 3
+        %exitcond = icmp eq i64 %indvar.next, 0
+        br i1 %exitcond, label %return, label %loop
+
+return:
+        ret void
+}
+
+define void @yet_another_count_up_signed(double* %d, i64 %n) nounwind {
+entry:
+        br label %loop
+
+loop:
+        %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %loop ]
+        %s0 = shl i64 %indvar, 8
+        %indvar.i8 = ashr i64 %s0, 8
+        %t0 = getelementptr double* %d, i64 %indvar.i8
+        %t1 = load double* %t0
+        %t2 = mul double %t1, 0.1
+        store double %t2, double* %t0
+        %s1 = shl i64 %indvar, 24
+        %indvar.i24 = ashr i64 %s1, 24
+        %t3 = getelementptr double* %d, i64 %indvar.i24
+        %t4 = load double* %t3
+        %t5 = mul double %t4, 2.3
+        store double %t5, double* %t3
+        %t6 = getelementptr double* %d, i64 %indvar
+        %t7 = load double* %t6
+        %t8 = mul double %t7, 4.5
+        store double %t8, double* %t6
+        %indvar.next = add i64 %indvar, 3
+        %exitcond = icmp eq i64 %indvar.next, 10
+        br i1 %exitcond, label %return, label %loop
+
+return:
+        ret void
+}
+
+define void @yet_another_count_down_signed(double* %d, i64 %n) nounwind {
+entry:
+        br label %loop
+
+loop:
+        %indvar = phi i64 [ 10, %entry ], [ %indvar.next, %loop ]
+        %s0 = shl i64 %indvar, 8
+        %indvar.i8 = ashr i64 %s0, 8
+        %t0 = getelementptr double* %d, i64 %indvar.i8
+        %t1 = load double* %t0
+        %t2 = mul double %t1, 0.1
+        store double %t2, double* %t0
+        %s1 = shl i64 %indvar, 24
+        %indvar.i24 = ashr i64 %s1, 24
+        %t3 = getelementptr double* %d, i64 %indvar.i24
+        %t4 = load double* %t3
+        %t5 = mul double %t4, 2.3
+        store double %t5, double* %t3
+        %t6 = getelementptr double* %d, i64 %indvar
+        %t7 = load double* %t6
+        %t8 = mul double %t7, 4.5
+        store double %t8, double* %t6
+        %indvar.next = sub i64 %indvar, 3
+        %exitcond = icmp eq i64 %indvar.next, 0
+        br i1 %exitcond, label %return, label %loop
+
+return:
+        ret void
+}
+
+
+
diff --git a/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-1.ll b/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-1.ll
index 06e2312..cb2f3aa 100644
--- a/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-1.ll
+++ b/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-1.ll
@@ -1,4 +1,4 @@
-; RUN: llvm-as < %s | llc --x86-asm-syntax=att | grep {cmpl	\$8}
+; RUN: llvm-as < %s | llc --x86-asm-syntax=att | grep {cmpq	\$8}
 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"
 target triple = "x86_64-apple-darwin9"
 
@@ -6,7 +6,7 @@
 ; happens after the relevant use, so the comparison stride can be
 ; easily changed.
 
-define void @foo() {
+define void @foo() nounwind {
 entry:
 	br label %loop
 
@@ -14,9 +14,11 @@
 	%indvar = phi i32 [ 0, %entry ], [ %i.2.0.us1534, %loop ]		; <i32> [#uses=1]
 	%i.2.0.us1534 = add i32 %indvar, 1		; <i32> [#uses=3]
 	%tmp628.us1540 = shl i32 %i.2.0.us1534, 1		; <i32> [#uses=1]
-	%tmp645646647.us1547 = sext i32 %tmp628.us1540 to i64		; <i64> [#uses=0]
+	%tmp645646647.us1547 = sext i32 %tmp628.us1540 to i64		; <i64> [#uses=1]
+	store i64 %tmp645646647.us1547, i64* null
 	%tmp611.us1535 = icmp eq i32 %i.2.0.us1534, 4		; <i1> [#uses=2]
-	%tmp623.us1538 = select i1 %tmp611.us1535, i32 6, i32 0		; <i32> [#uses=0]
+	%tmp623.us1538 = select i1 %tmp611.us1535, i32 6, i32 0		; <i32> [#uses=1]
+	store i32 %tmp623.us1538, i32* null
 	br i1 %tmp611.us1535, label %exit, label %loop
 
 exit: