xref: /aosp_15_r20/external/llvm/test/CodeGen/ARM/copy-cpsr.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=armv7s-apple-ios7.0 -show-mc-encoding %s -o - | FileCheck %s --check-prefix=CHECK-ARM
2*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=thumbv7s-apple-ios7.0 -show-mc-encoding %s -o - | FileCheck %s --check-prefix=CHECK-THUMB
3*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=thumbv7m-none-eabi -show-mc-encoding %s -o - | FileCheck %s --check-prefix=CHECK-THUMB
4*9880d681SAndroid Build Coastguard Worker
5*9880d681SAndroid Build Coastguard Worker; In the ARM backend, most compares are glued to their uses so CPSR can't
6*9880d681SAndroid Build Coastguard Worker; escape. However, for long ADCS chains (and last ditch fallback) the dependency
7*9880d681SAndroid Build Coastguard Worker; is carried in the DAG because duplicating them can be more expensive than
8*9880d681SAndroid Build Coastguard Worker; copying CPSR.
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Worker; Crafting a test for this was a little tricky, in case it breaks here are some
11*9880d681SAndroid Build Coastguard Worker; notes on what I was tring to achieve:
12*9880d681SAndroid Build Coastguard Worker;   + We want 2 long ADCS chains
13*9880d681SAndroid Build Coastguard Worker;   + We want them to split after an initial common prefix (so that a single
14*9880d681SAndroid Build Coastguard Worker;     CPSR is used twice).
15*9880d681SAndroid Build Coastguard Worker;   + We want both chains to write CPSR post-split (so that the copy can't be
16*9880d681SAndroid Build Coastguard Worker;     elided).
17*9880d681SAndroid Build Coastguard Worker;   + We want the chains to be long enough that duplicating them is expensive.
18*9880d681SAndroid Build Coastguard Worker
19*9880d681SAndroid Build Coastguard Workerdefine void @test_copy_cpsr(i128 %lhs, i128 %rhs, i128* %addr) {
20*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: test_copy_cpsr:
21*9880d681SAndroid Build Coastguard Worker; CHECK-THUMB: test_copy_cpsr:
22*9880d681SAndroid Build Coastguard Worker
23*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: mrs [[TMP:r[0-9]+]], apsr @ encoding: [0x00,0x{{[0-9a-f]}}0,0x0f,0xe1]
24*9880d681SAndroid Build Coastguard Worker; CHECK-ARM: msr APSR_nzcvq, [[TMP]] @ encoding: [0x0{{[0-9a-f]}},0xf0,0x28,0xe1]
25*9880d681SAndroid Build Coastguard Worker
26*9880d681SAndroid Build Coastguard Worker  ; In Thumb mode v7M and v7AR have different MRS/MSR instructions that happen
27*9880d681SAndroid Build Coastguard Worker  ; to overlap for the apsr case, so it's definitely worth checking both.
28*9880d681SAndroid Build Coastguard Worker; CHECK-THUMB: mrs [[TMP:r[0-9]+]], apsr @ encoding: [0xef,0xf3,0x00,0x8{{[0-9a-f]}}]
29*9880d681SAndroid Build Coastguard Worker; CHECK-THUMB: msr {{APSR|apsr}}_nzcvq, [[TMP]] @ encoding: [0x8{{[0-9a-f]}},0xf3,0x00,0x88]
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Worker  %sum = add i128 %lhs, %rhs
32*9880d681SAndroid Build Coastguard Worker  store volatile i128 %sum, i128* %addr
33*9880d681SAndroid Build Coastguard Worker
34*9880d681SAndroid Build Coastguard Worker  %rhs2.tmp1 = trunc i128 %rhs to i64
35*9880d681SAndroid Build Coastguard Worker  %rhs2 = zext i64 %rhs2.tmp1 to i128
36*9880d681SAndroid Build Coastguard Worker
37*9880d681SAndroid Build Coastguard Worker  %sum2 = add i128 %lhs, %rhs2
38*9880d681SAndroid Build Coastguard Worker  store volatile i128 %sum2, i128* %addr
39*9880d681SAndroid Build Coastguard Worker
40*9880d681SAndroid Build Coastguard Worker  ret void
41*9880d681SAndroid Build Coastguard Worker}
42