brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.3 KiB · eae2e82 Raw
218 lines · plain
1; RUN: split-file %s %t2; RUN: cat %t/main.ll %t/_align32.ll > %t/align32.ll3; RUN: llc -mtriple=x86_64-pc-linux-gnu -mattr=+mwaitx -x86-use-base-pointer=true -stackrealign %t/align32.ll -o - | FileCheck --check-prefix=CHECK --check-prefix=USE_BASE_64 %s4; RUN: llc -mtriple=x86_64-pc-linux-gnux32 -mattr=+mwaitx -x86-use-base-pointer=true -stackrealign %t/align32.ll -o - | FileCheck --check-prefix=CHECK --check-prefix=USE_BASE_32 %s5; RUN: llc -mtriple=x86_64-pc-linux-gnu -mattr=+mwaitx -x86-use-base-pointer=true %t/main.ll -o - | FileCheck --check-prefix=CHECK --check-prefix=NO_BASE_64 %s6; RUN: llc -mtriple=x86_64-pc-linux-gnux32 -mattr=+mwaitx -x86-use-base-pointer=true %t/main.ll -o - | FileCheck --check-prefix=CHECK --check-prefix=NO_BASE_32 %s7 8;--- main.ll9 10; This test checks that we save and restore the base pointer (ebx or rbx) in the11; presence of the mwaitx intrinsic which requires to use ebx for one of its12; argument.13; This function uses a dynamically allocated stack to force the use14; of a base pointer.15; After the call to the mwaitx intrinsic we do a volatile store to the16; dynamically allocated memory which will require the use of the base pointer.17; The base pointer should therefore be restored straight after the mwaitx18; instruction.19 20define void @test_baseptr(i64 %x, i64 %y, i32 %E, i32 %H, i32 %C) nounwind {21entry:22  %ptr = alloca ptr, align 823  %0 = alloca i8, i64 %x, align 1624  store ptr %0, ptr %ptr, align 825  call void @llvm.x86.mwaitx(i32 %E, i32 %H, i32 %C)26  %1 = load ptr, ptr %ptr, align 827  %arrayidx = getelementptr inbounds i8, ptr %1, i64 %y28  store volatile i8 42, ptr %arrayidx, align 129  ret void30}31; CHECK-LABEL: test_baseptr:32; USE_BASE_64: movq %rsp, %rbx33; Pass mwaitx first 2 arguments in eax and ecx respectively.34; USE_BASE_64: movl %ecx, %eax35; USE_BASE_64: movl %edx, %ecx36; Save base pointer.37; USE_BASE_64: movq %rbx, [[SAVE_rbx:%r([8-9]|1[0-5]|di|si)]]38; Set mwaitx ebx argument.39; USE_BASE_64: movl %r8d, %ebx40; USE_BASE_64-NEXT: mwaitx41; Restore base pointer.42; USE_BASE_64-NEXT: movq [[SAVE_rbx]], %rbx43 44; USE_BASE_32: movl %esp, %ebx45; Pass mwaitx first 2 arguments in eax and ecx respectively.46; USE_BASE_32: movl %ecx, %eax47; USE_BASE_32: movl %edx, %ecx48; Save base pointer.49; USE_BASE_32: movq %rbx, [[SAVE_rbx:%r(di|si)]]50; Set mwaitx ebx argument.51; USE_BASE_32: movl %r8d, %ebx52; USE_BASE_32-NEXT: mwaitx53; Restore base pointer.54; USE_BASE_32-NEXT: movq [[SAVE_rbx]], %rbx55 56; Pass mwaitx 3 arguments in eax, ecx, ebx57; NO_BASE_64: movl %ecx, %eax58; NO_BASE_64: movl %edx, %ecx59; NO_BASE_64: movl %r8d, %ebx60; No need to save base pointer.61; NO_BASE_64-NOT: movq %rbx62; NO_BASE_64: mwaitx63; No need to restore base pointer.64; NO_BASE_64-NOT: movq {{.*}}, %rbx65; NO_BASE_64-NEXT: {{.+$}}66 67; Pass mwaitx 3 arguments in eax, ecx, ebx68; NO_BASE_32: movl %ecx, %eax69; NO_BASE_32: movl %edx, %ecx70; NO_BASE_32: movl %r8d, %ebx71; No need to save base pointer.72; NO_BASE_32-NOT: movl %ebx73; NO_BASE_32: mwaitx74; No need to restore base pointer.75; NO_BASE_32-NOT: movl {{.*}}, %ebx76; NO_BASE_32-NEXT: {{.+$}}77 78; Test of the case where an opaque sp adjustement is introduced by a separate79; basic block which, combined with stack realignment, requires a base pointer.80@g = global i32 0, align 881 82define void @test_opaque_sp_adjustment(i32 %E, i32 %H, i32 %C, i64 %x) {83entry:84  %ptr = alloca ptr, align 885  call void @llvm.x86.mwaitx(i32 %E, i32 %H, i32 %C)86  %g = load i32, ptr @g, align 487  %tobool = icmp ne i32 %g, 088  br i1 %tobool, label %if.then, label %if.end89 90if.then:91  call void asm sideeffect "", "~{rsp},~{esp},~{dirflag},~{fpsr},~{flags}"()92  br label %if.end93 94if.end:95  %ptr2 = load ptr, ptr %ptr, align 896  %arrayidx = getelementptr inbounds i8, ptr %ptr2, i64 %x97  store volatile i8 42, ptr %arrayidx, align 198  ret void99}100; CHECK-LABEL: test_opaque_sp_adjustment:101; USE_BASE_64: movq %rsp, %rbx102; Pass mwaitx first 2 arguments in eax and ecx respectively.103; USE_BASE_64: movl %esi, %eax104; USE_BASE_64: movl %edi, %ecx105; Save base pointer.106; USE_BASE_64: movq %rbx, [[SAVE_rbx:%r([8-9]|1[0-5]|di|si)]]107; Set mwaitx ebx argument.108; USE_BASE_64: movl %edx, %ebx109; USE_BASE_64-NEXT: mwaitx110; Restore base pointer.111; USE_BASE_64-NEXT: movq [[SAVE_rbx]], %rbx112 113; USE_BASE_32: movl %esp, %ebx114; Pass mwaitx first 2 arguments in eax and ecx respectively.115; USE_BASE_32: movl %esi, %eax116; USE_BASE_32: movl %edi, %ecx117; Save base pointer.118; USE_BASE_32: movq %rbx, [[SAVE_rbx:%r(di|si)]]119; Set mwaitx ebx argument.120; USE_BASE_32: movl %edx, %ebx121; USE_BASE_32-NEXT: mwaitx122; Restore base pointer.123; USE_BASE_32-NEXT: movq [[SAVE_rbx]], %rbx124 125; Pass mwaitx 3 arguments in eax, ecx, ebx126; NO_BASE_64: movl %esi, %eax127; NO_BASE_64: movl %edi, %ecx128; NO_BASE_64: movl %edx, %ebx129; No need to save base pointer.130; NO_BASE_64-NOT: movq %rbx131; NO_BASE_64: mwaitx132; NO_BASE_64-NOT: movq {{.*}}, %rbx133; NO_BASE_64-NEXT: {{.+$}}134 135; Pass mwaitx 3 arguments in eax, ecx, ebx136; NO_BASE_32: movl %esi, %eax137; NO_BASE_32: movl %edi, %ecx138; NO_BASE_32: movl %edx, %ebx139; No need to save base pointer.140; NO_BASE_32-NOT: movl %ebx141; NO_BASE_32: mwaitx142; No need to restore base pointer.143; NO_BASE_32-NOT: movl {{.*}}, %ebx144; NO_BASE_32-NEXT: {{.+$}}145 146; Test of the case where a variable size object is introduced by a separate147; basic block which, combined with stack realignment, requires a base pointer.148define void @test_variable_size_object(i32 %E, i32 %H, i32 %C, i64 %x) {149entry:150  %ptr = alloca ptr, align 8151  call void @llvm.x86.mwaitx(i32 %E, i32 %H, i32 %C)152  %g = load i32, ptr @g, align 4153  %tobool = icmp ne i32 %g, 0154  br i1 %tobool, label %if.then, label %if.end155 156if.then:157  %i5 = alloca i8, i64 %x, align 16158  store ptr %i5, ptr %ptr, align 8159  br label %if.end160 161if.end:162  %ptr2 = load ptr, ptr %ptr, align 8163  %arrayidx = getelementptr inbounds i8, ptr %ptr2, i64 %x164  store volatile i8 42, ptr %arrayidx, align 1165  ret void166}167 168; CHECK-LABEL: test_variable_size_object:169; USE_BASE_64: movq %rsp, %rbx170; Pass mwaitx first 2 arguments in eax and ecx respectively.171; USE_BASE_64: movl %esi, %eax172; USE_BASE_64: movl %edi, %ecx173; Save base pointer.174; USE_BASE_64: movq %rbx, [[SAVE_rbx:%r([8-9]|1[0-5]|di|si)]]175; Set mwaitx ebx argument.176; USE_BASE_64: movl %edx, %ebx177; USE_BASE_64-NEXT: mwaitx178; Restore base pointer.179; USE_BASE_64-NEXT: movq [[SAVE_rbx]], %rbx180 181; USE_BASE_32: movl %esp, %ebx182; Pass mwaitx first 2 arguments in eax and ecx respectively.183; USE_BASE_32: movl %esi, %eax184; USE_BASE_32: movl %edi, %ecx185; Save base pointer.186; USE_BASE_32: movq %rbx, [[SAVE_rbx:%r(di|si)]]187; Set mwaitx ebx argument.188; USE_BASE_32: movl %edx, %ebx189; USE_BASE_32-NEXT: mwaitx190; Restore base pointer.191; USE_BASE_32-NEXT: movq [[SAVE_rbx]], %rbx192 193; Pass mwaitx 3 arguments in eax, ecx, ebx194; NO_BASE_64: movl %esi, %eax195; NO_BASE_64: movl %edi, %ecx196; NO_BASE_64: movl %edx, %ebx197; No need to save base pointer.198; NO_BASE_64-NOT: movq %rbx199; NO_BASE_64: mwaitx200; NO_BASE_64-NOT: movq {{.*}}, %rbx201; NO_BASE_64-NEXT: {{.+$}}202 203; Pass mwaitx 3 arguments in eax, ecx, ebx204; NO_BASE_32: movl %esi, %eax205; NO_BASE_32: movl %edi, %ecx206; NO_BASE_32: movl %edx, %ebx207; No need to save base pointer.208; NO_BASE_32-NOT: movl %ebx209; NO_BASE_32: mwaitx210; No need to restore base pointer.211; NO_BASE_32-NOT: movl {{.*}}, %ebx212; NO_BASE_32-NEXT: {{.+$}}213 214declare void @llvm.x86.mwaitx(i32, i32, i32) nounwind215;--- _align32.ll216!llvm.module.flags = !{!0}217!0 = !{i32 2, !"override-stack-alignment", i32 32}218