aboutsummaryrefslogtreecommitdiffstats
path: root/test/CodeGen/ARM/2012-03-26-FoldImmBug.ll
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2012-03-26 23:31:00 +0000
committerEvan Cheng <evan.cheng@apple.com>2012-03-26 23:31:00 +0000
commite279f5953e9c3d934248cd4d2f24b6179ad9d2e6 (patch)
tree1055c81a7dd2b71ad363a160169a3f1eb2b23307 /test/CodeGen/ARM/2012-03-26-FoldImmBug.ll
parent20df03ccd572aefadc3d68e4abc2e58c0bef9ff7 (diff)
downloadexternal_llvm-e279f5953e9c3d934248cd4d2f24b6179ad9d2e6.zip
external_llvm-e279f5953e9c3d934248cd4d2f24b6179ad9d2e6.tar.gz
external_llvm-e279f5953e9c3d934248cd4d2f24b6179ad9d2e6.tar.bz2
ARM has a peephole optimization which looks for a def / use pair. The def
produces a 32-bit immediate which is consumed by the use. It tries to fold the immediate by breaking it into two parts and fold them into the immmediate fields of two uses. e.g movw r2, #40885 movt r3, #46540 add r0, r0, r3 => add.w r0, r0, #3019898880 add.w r0, r0, #30146560 ; However, this transformation is incorrect if the user produces a flag. e.g. movw r2, #40885 movt r3, #46540 adds r0, r0, r3 => add.w r0, r0, #3019898880 adds.w r0, r0, #30146560 Note the adds.w may not set the carry flag even if the original sequence would. rdar://11116189 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153484 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGen/ARM/2012-03-26-FoldImmBug.ll')
-rw-r--r--test/CodeGen/ARM/2012-03-26-FoldImmBug.ll33
1 files changed, 33 insertions, 0 deletions
diff --git a/test/CodeGen/ARM/2012-03-26-FoldImmBug.ll b/test/CodeGen/ARM/2012-03-26-FoldImmBug.ll
new file mode 100644
index 0000000..0ff4f51
--- /dev/null
+++ b/test/CodeGen/ARM/2012-03-26-FoldImmBug.ll
@@ -0,0 +1,33 @@
+; RUN: llc < %s -mtriple=thumbv7-apple-ios -mcpu=cortex-a8 | FileCheck %s
+
+; ARM has a peephole optimization which looks for a def / use pair. The def
+; produces a 32-bit immediate which is consumed by the use. It tries to
+; fold the immediate by breaking it into two parts and fold them into the
+; immmediate fields of two uses. e.g
+; movw r2, #40885
+; movt r3, #46540
+; add r0, r0, r3
+; =>
+; add.w r0, r0, #3019898880
+; add.w r0, r0, #30146560
+;
+; However, this transformation is incorrect if the user produces a flag. e.g.
+; movw r2, #40885
+; movt r3, #46540
+; adds r0, r0, r3
+; =>
+; add.w r0, r0, #3019898880
+; adds.w r0, r0, #30146560
+; Note the adds.w may not set the carry flag even if the original sequence
+; would.
+;
+; rdar://11116189
+define i64 @t(i64 %aInput) nounwind {
+; CHECK: t:
+; CHECK: movs [[REG:(r[0-9]+)]], #0
+; CHECK: movt [[REG]], #46540
+; CHECK: adds r{{[0-9]+}}, r{{[0-9]+}}, [[REG]]
+ %1 = mul i64 %aInput, 1000000
+ %2 = add i64 %1, -7952618389194932224
+ ret i64 %2
+}