Home | History | Annotate | Download | only in X86
      1 ; RUN: llc -mtriple=x86_64-apple-macosx -mattr=+cx16 -x86-use-base-pointer=true -stackrealign -stack-alignment=32  %s -o - | FileCheck --check-prefix=CHECK --check-prefix=USE_BASE --check-prefix=USE_BASE_64 %s
      2 ; RUN: llc -mtriple=x86_64-apple-macosx -mattr=+cx16 -x86-use-base-pointer=false -stackrealign -stack-alignment=32  %s -o - | FileCheck --check-prefix=CHECK --check-prefix=DONT_USE_BASE %s
      3 ; RUN: llc -mtriple=x86_64-linux-gnux32 -mattr=+cx16 -x86-use-base-pointer=true -stackrealign -stack-alignment=32  %s -o - | FileCheck --check-prefix=CHECK --check-prefix=USE_BASE --check-prefix=USE_BASE_32 %s
      4 ; RUN: llc -mtriple=x86_64-linux-gnux32 -mattr=+cx16 -x86-use-base-pointer=false -stackrealign -stack-alignment=32  %s -o - | FileCheck --check-prefix=CHECK --check-prefix=DONT_USE_BASE %s
      5 
      6 ; This function uses dynamic allocated stack to force the use
      7 ; of a frame pointer.
      8 ; The inline asm clobbers a bunch of registers to make sure
      9 ; 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 requires
     13 ; to clobbers rbx to set the arguments of the instruction and when
     14 ; 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, %rbx
     20 ; USE_BASE_32: movl %esp, %ebx
     21 ;
     22 ; Make sure the base pointer is saved before the RBX argument for
     23 ; 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 use
     31 ; by cmpxchg. Since such regex would be complicated to write, just stick
     32 ; to the numbered registers. The bottom line is: if this test case fails
     33 ; 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 {{[^ ]+}}, %rbx
     37 ; USE_BASE-NEXT: cmpxchg16b
     38 ; USE_BASE-NEXT: movq [[SAVE_RBX]], %rbx
     39 ;
     40 ; DONT_USE_BASE-NOT: movq %rsp, %rbx
     41 ; DONT_USE_BASE-NOT: movl %esp, %ebx
     42 ; DONT_USE_BASE: cmpxchg
     43 define i1 @cmp_and_swap16(i128 %a, i128 %b, i128* %addr, i32 %n) {
     44   %dummy = alloca i32, i32 %n
     45 tail call void asm sideeffect "nop", "~{rax},~{rcx},~{rdx},~{rsi},~{rdi},~{rbp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15}"()
     46   %cmp = cmpxchg i128* %addr, i128 %a, i128 %b seq_cst seq_cst
     47   %res = extractvalue { i128, i1 } %cmp, 1
     48   %idx = getelementptr i32, i32* %dummy, i32 5
     49   store i32 %n, i32* %idx
     50   ret i1 %res
     51 }
     52