brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.5 KiB · 3252c13 Raw
203 lines · plain
1; RUN: llc -mtriple armv7a--none-eabi < %s              | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLED2; RUN: llc -mtriple armv7a--none-eabi < %s -enable-ipra | FileCheck %s --check-prefix=CHECK --check-prefix=ENABLED3 4define void @leaf()  {5entry:6  tail call void asm sideeffect "", ""()7  ret void8}9 10define void @leaf_r3() {11entry:12  tail call void asm sideeffect "", "~{r3}"()13  ret void14}15 16define void @leaf_r4() {17entry:18  tail call void asm sideeffect "", "~{r4}"()19  ret void20}21 22define void @leaf_s0() {23entry:24  tail call void asm sideeffect "", "~{s0}"()25  ret void26}27 28define void @leaf_d0() {29entry:30  tail call void asm sideeffect "", "~{d0}"()31  ret void32}33 34; r3 is normally caller-saved, but with IPRA we can see that it isn't used in35; the callee, so can leave a live value in it.36define void @test_r3_presrved() {37; CHECK-LABEL: test_r3_presrved:38entry:39; CHECK: ASM1: r340; DISABLED: mov [[TEMP:r[0-9]+]], r341; ENABLED-NOT: r342; CHECK: bl      leaf43; DISABLED: mov r3, [[TEMP]]44; ENABLED-NOT: r345; CHECK: ASM2: r346  %a = tail call i32 asm sideeffect "// ASM1: $0", "={r3},0"(i32 undef)47  tail call void @leaf()48  %b = tail call i32 asm sideeffect "// ASM2: $0", "={r3},0"(i32 %a)49  ret void50}51 52; Same as above, but r3 is clobbered in the callee, so it is clobbered by the53; call as normal.54define void @test_r3_clobbered() {55; CHECK-LABEL: test_r3_clobbered:56entry:57; CHECK: ASM1: r358; CHECK: mov [[TEMP:r[0-9]+]], r359; CHECK: bl      leaf60; CHECK: mov r3, [[TEMP]]61; CHECK: ASM2: r362  %a = tail call i32 asm sideeffect "// ASM1: $0", "={r3},0"(i32 undef)63  tail call void @leaf_r3()64  %b = tail call i32 asm sideeffect "// ASM2: $0", "={r3},0"(i32 %a)65  ret void66}67 68; r4 is a callee-saved register, so IPRA has no effect.69define void @test_r4_preserved() {70; CHECK-LABEL: test_r4_preserved:71entry:72; CHECK: ASM1: r473; CHECK-NOT: r474; CHECK: bl      leaf75; CHECK-NOT: r476; CHECK: ASM2: r477  %a = tail call i32 asm sideeffect "// ASM1: $0", "={r4},0"(i32 undef)78  tail call void @leaf()79  %b = tail call i32 asm sideeffect "// ASM2: $0", "={r4},0"(i32 %a)80  ret void81}82define void @test_r4_clobbered() {83; CHECK-LABEL: test_r4_clobbered:84entry:85; CHECK: ASM1: r486; CHECK-NOT: r487; CHECK: bl      leaf_r488; CHECK-NOT: r489; CHECK: ASM2: r490  %a = tail call i32 asm sideeffect "// ASM1: $0", "={r4},0"(i32 undef)91  tail call void @leaf_r4()92  %b = tail call i32 asm sideeffect "// ASM2: $0", "={r4},0"(i32 %a)93  ret void94}95 96; r12 is the intra-call scratch register, so we have to assume it is clobbered97; even if we can see that the callee does not touch it.98define void @test_r12() {99; CHECK-LABEL: test_r12:100entry:101; CHECK: ASM1: r12102; CHECK: mov [[TEMP:r[0-9]+]], r12103; CHECK: bl      leaf104; CHECK: mov r12, [[TEMP]]105; CHECK: ASM2: r12106  %a = tail call i32 asm sideeffect "// ASM1: $0", "={r12},0"(i32 undef)107  tail call void @leaf()108  %b = tail call i32 asm sideeffect "// ASM2: $0", "={r12},0"(i32 %a)109  ret void110}111 112; s0 and d0 are caller-saved, IPRA allows us to keep them live in the caller if113; the callee doesn't modify them.114define void @test_s0_preserved() {115; CHECK-LABEL: test_s0_preserved:116entry:117; CHECK: ASM1: s0118; DISABLED: vmov.f32 [[TEMP:s[0-9]+]], s0119; ENABLED-NOT: s0120; CHECK: bl      leaf121; DISABLED: vmov.f32 s0, [[TEMP]]122; ENABLED-NOT: s0123; CHECK: ASM2: s0124  %a = tail call float asm sideeffect "// ASM1: $0", "={s0},0"(float undef)125  tail call void @leaf()126  %b = tail call float asm sideeffect "// ASM2: $0", "={s0},0"(float %a)127  ret void128}129 130define void @test_s0_clobbered() {131; CHECK-LABEL: test_s0_clobbered:132entry:133; CHECK: ASM1: s0134; CHECK: vmov.f32 [[TEMP:s[0-9]+]], s0135; CHECK: bl      leaf_s0136; CHECK: vmov.f32 s0, [[TEMP]]137; CHECK: ASM2: s0138  %a = tail call float asm sideeffect "// ASM1: $0", "={s0},0"(float undef)139  tail call void @leaf_s0()140  %b = tail call float asm sideeffect "// ASM2: $0", "={s0},0"(float %a)141  ret void142}143 144define void @test_d0_preserved() {145; CHECK-LABEL: test_d0_preserved:146entry:147; CHECK: ASM1: d0148; DISABLED: vmov.f64 [[TEMP:d[0-9]+]], d0149; ENABLED-NOT: d0150; CHECK: bl      leaf151; DISABLED: vmov.f64 d0, [[TEMP]]152; ENABLED-NOT: d0153; CHECK: ASM2: d0154  %a = tail call double asm sideeffect "// ASM1: $0", "={d0},0"(double undef)155  tail call void @leaf()156  %b = tail call double asm sideeffect "// ASM2: $0", "={d0},0"(double %a)157  ret void158}159 160define void @test_d0_clobbered() {161; CHECK-LABEL: test_d0_clobbered:162entry:163; CHECK: ASM1: d0164; CHECK: vmov.f64 [[TEMP:d[0-9]+]], d0165; CHECK: bl      leaf_d0166; CHECK: vmov.f64 d0, [[TEMP]]167; CHECK: ASM2: d0168  %a = tail call double asm sideeffect "// ASM1: $0", "={d0},0"(double undef)169  tail call void @leaf_d0()170  %b = tail call double asm sideeffect "// ASM2: $0", "={d0},0"(double %a)171  ret void172}173 174; s0 and d0 overlap, so clobbering one in the callee prevents the other from175; being kept live across the call.176define void @test_s0_clobber_d0() {177; CHECK-LABEL: test_s0_clobber_d0:178entry:179; CHECK: ASM1: s0180; CHECK: vmov.f32 [[TEMP:s[0-9]+]], s0181; CHECK: bl      leaf_d0182; CHECK: vmov.f32 s0, [[TEMP]]183; CHECK: ASM2: s0184  %a = tail call float asm sideeffect "// ASM1: $0", "={s0},0"(float undef)185  tail call void @leaf_d0()186  %b = tail call float asm sideeffect "// ASM2: $0", "={s0},0"(float %a)187  ret void188}189 190define void @test_d0_clobber_s0() {191; CHECK-LABEL: test_d0_clobber_s0:192entry:193; CHECK: ASM1: d0194; CHECK: vmov.f64 [[TEMP:d[0-9]+]], d0195; CHECK: bl      leaf_s0196; CHECK: vmov.f64 d0, [[TEMP]]197; CHECK: ASM2: d0198  %a = tail call double asm sideeffect "// ASM1: $0", "={d0},0"(double undef)199  tail call void @leaf_s0()200  %b = tail call double asm sideeffect "// ASM2: $0", "={d0},0"(double %a)201  ret void202}203