xref: /llvm-project/llvm/test/CodeGen/ARM/2012-03-26-FoldImmBug.ll (revision d24ab20e9b11d2076d8b9d5cd96f41a6b9c399fb)
1a2b48d98SEvan Cheng; RUN: llc < %s -mtriple=thumbv7-apple-ios -mcpu=cortex-a8 | FileCheck %s
2a2b48d98SEvan Cheng
3a2b48d98SEvan Cheng; ARM has a peephole optimization which looks for a def / use pair. The def
4a2b48d98SEvan Cheng; produces a 32-bit immediate which is consumed by the use. It tries to
5a2b48d98SEvan Cheng; fold the immediate by breaking it into two parts and fold them into the
6a2b48d98SEvan Cheng; immmediate fields of two uses. e.g
7a2b48d98SEvan Cheng;        movw    r2, #40885
8a2b48d98SEvan Cheng;        movt    r3, #46540
9a2b48d98SEvan Cheng;        add     r0, r0, r3
10a2b48d98SEvan Cheng; =>
11a2b48d98SEvan Cheng;        add.w   r0, r0, #3019898880
12a2b48d98SEvan Cheng;        add.w   r0, r0, #30146560
13a2b48d98SEvan Cheng;
14a2b48d98SEvan Cheng; However, this transformation is incorrect if the user produces a flag. e.g.
15a2b48d98SEvan Cheng;        movw    r2, #40885
16a2b48d98SEvan Cheng;        movt    r3, #46540
17a2b48d98SEvan Cheng;        adds    r0, r0, r3
18a2b48d98SEvan Cheng; =>
19a2b48d98SEvan Cheng;        add.w   r0, r0, #3019898880
20a2b48d98SEvan Cheng;        adds.w  r0, r0, #30146560
21a2b48d98SEvan Cheng; Note the adds.w may not set the carry flag even if the original sequence
22a2b48d98SEvan Cheng; would.
23a2b48d98SEvan Cheng;
24a2b48d98SEvan Cheng; rdar://11116189
25a2b48d98SEvan Chengdefine i64 @t(i64 %aInput) nounwind {
26*d24ab20eSStephen Lin; CHECK-LABEL: t:
27a2b48d98SEvan Cheng; CHECK: movs [[REG:(r[0-9]+)]], #0
28a2b48d98SEvan Cheng; CHECK: movt [[REG]], #46540
29a2b48d98SEvan Cheng; CHECK: adds r{{[0-9]+}}, r{{[0-9]+}}, [[REG]]
30a2b48d98SEvan Cheng  %1 = mul i64 %aInput, 1000000
31a2b48d98SEvan Cheng  %2 = add i64 %1, -7952618389194932224
32a2b48d98SEvan Cheng  ret i64 %2
33a2b48d98SEvan Cheng}
34