brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.0 KiB · 5e8da58 Raw
88 lines · plain
1; RUN: llc -mtriple=x86_64-apple-macosx -mattr=+cx16 -x86-use-base-pointer=true -stackrealign %s -o - | FileCheck --check-prefix=CHECK --check-prefix=USE_BASE --check-prefix=USE_BASE_64 %s2; RUN: llc -mtriple=x86_64-apple-macosx -mattr=+cx16 -x86-use-base-pointer=false -stackrealign %s -o - | FileCheck --check-prefix=CHECK --check-prefix=DONT_USE_BASE %s3; RUN: llc -mtriple=x86_64-linux-gnux32 -mattr=+cx16 -x86-use-base-pointer=true -stackrealign %s -o - | FileCheck --check-prefix=CHECK --check-prefix=USE_BASE --check-prefix=USE_BASE_32 %s4; RUN: llc -mtriple=x86_64-linux-gnux32 -mattr=+cx16 -x86-use-base-pointer=false -stackrealign %s -o - | FileCheck --check-prefix=CHECK --check-prefix=DONT_USE_BASE %s5 6; This function uses dynamic allocated stack to force the use7; of a frame pointer.8; The inline asm clobbers a bunch of registers to make sure9; the frame pointer will need to be used (for spilling in that case).10;11; Then, we check that when we use rbx as the base pointer,12; we do not use cmpxchg, since using that instruction requires13; to clobbers rbx to set the arguments of the instruction and when14; rbx is used as the base pointer, RA cannot fix the code for us.15;16; CHECK-LABEL: cmp_and_swap16:17; Check that we actually use rbx.18; gnux32 use the 32bit variant of the registers.19; USE_BASE_64: movq %rsp, %rbx20; USE_BASE_32: movl %esp, %ebx21;22; Make sure the base pointer is saved before the rbx argument for23; cmpxchg16b is set.24;25; Because of how the test is written, we spill SAVE_rbx.26; However, it would have been perfectly fine to just keep it in register.27; USE_BASE: movq %rbx, [[SAVE_rbx_SLOT:[0-9]*\(%[er]bx\)]]28;29; SAVE_rbx must be in register before we clobber rbx.30; It is fine to use any register but rbx and the ones defined and use31; by cmpxchg. Since such regex would be complicated to write, just stick32; to the numbered registers. The bottom line is: if this test case fails33; because of that regex, this is likely just the regex being too conservative. 34; USE_BASE: movq [[SAVE_rbx_SLOT]], [[SAVE_rbx:%r[0-9]+]]35;36; USE_BASE: movq {{[^ ]+}}, %rbx37; USE_BASE-NEXT: cmpxchg16b38; USE_BASE-NEXT: movq [[SAVE_rbx]], %rbx39;40; DONT_USE_BASE-NOT: movq %rsp, %rbx41; DONT_USE_BASE-NOT: movl %esp, %ebx42; DONT_USE_BASE: cmpxchg43define i1 @cmp_and_swap16(i128 %a, i128 %b, ptr %addr, i32 %n) {44  %dummy = alloca i32, i32 %n45tail call void asm sideeffect "nop", "~{rax},~{rcx},~{rdx},~{rsi},~{rdi},~{rbp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15}"()46  %cmp = cmpxchg ptr %addr, i128 %a, i128 %b seq_cst seq_cst47  %res = extractvalue { i128, i1 } %cmp, 148  %idx = getelementptr i32, ptr %dummy, i32 549  store i32 %n, ptr %idx50  ret i1 %res51}52 53; If we compare-and-exchange a frame variable, we additionally need to rewrite54; the memory operand to use the SAVE_rbx instead of rbx, which already contains55; the input operand.56;57; CHECK-LABEL: cmp_and_swap16_frame:58; Check that we actually use rbx.59; gnux32 use the 32bit variant of the registers.60; USE_BASE_64: movq %rsp, %rbx61; USE_BASE_32: movl %esp, %ebx62; Here we drop the inline assembly because the frame pointer is used anyway. So63; rbx is not spilled to the stack but goes into a (hopefully numbered) register.64; USE_BASE: movq %rbx, [[SAVE_rbx:%r[0-9]+]]65;66; USE_BASE: movq {{[^ ]+}}, %rbx67; The use of the frame variable expands to N(%rbx) or N(%ebx). But we've just68; overwritten that with the input operand. We need to use SAVE_rbx instead.69; USE_BASE_64-NEXT: cmpxchg16b {{[0-9]*}}([[SAVE_rbx]])70; USE_BASE_32-NEXT: cmpxchg16b {{[0-9]*}}([[SAVE_rbx]]d)71; USE_BASE-NEXT: movq [[SAVE_rbx]], %rbx72;73; DONT_USE_BASE-NOT: movq %rsp, %rbx74; DONT_USE_BASE-NOT: movl %esp, %ebx75; DONT_USE_BASE: cmpxchg76define i1 @cmp_and_swap16_frame(i128 %a, i128 %b, i32 %n) {77  %local = alloca i128, align 1678  %dummy = alloca i32, i32 %n79  %cmp = cmpxchg ptr %local, i128 %a, i128 %b seq_cst seq_cst80  %res = extractvalue { i128, i1 } %cmp, 181  %idx = getelementptr i32, ptr %dummy, i32 582  store i32 %n, ptr %idx83  ret i1 %res84}85 86!llvm.module.flags = !{!0}87!0 = !{i32 2, !"override-stack-alignment", i32 32}88