1*9880d681SAndroid Build Coastguard Worker; 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*9880d681SAndroid Build Coastguard Worker; 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*9880d681SAndroid Build Coastguard Worker; 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*9880d681SAndroid Build Coastguard Worker; 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*9880d681SAndroid Build Coastguard Worker 6*9880d681SAndroid Build Coastguard Worker; This function uses dynamic allocated stack to force the use 7*9880d681SAndroid Build Coastguard Worker; of a frame pointer. 8*9880d681SAndroid Build Coastguard Worker; The inline asm clobbers a bunch of registers to make sure 9*9880d681SAndroid Build Coastguard Worker; the frame pointer will need to be used (for spilling in that case). 10*9880d681SAndroid Build Coastguard Worker; 11*9880d681SAndroid Build Coastguard Worker; Then, we check that when we use rbx as the base pointer, 12*9880d681SAndroid Build Coastguard Worker; we do not use cmpxchg, since using that instruction requires 13*9880d681SAndroid Build Coastguard Worker; to clobbers rbx to set the arguments of the instruction and when 14*9880d681SAndroid Build Coastguard Worker; rbx is used as the base pointer, RA cannot fix the code for us. 15*9880d681SAndroid Build Coastguard Worker; 16*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: cmp_and_swap16: 17*9880d681SAndroid Build Coastguard Worker; Check that we actually use rbx. 18*9880d681SAndroid Build Coastguard Worker; gnux32 use the 32bit variant of the registers. 19*9880d681SAndroid Build Coastguard Worker; USE_BASE_64: movq %rsp, %rbx 20*9880d681SAndroid Build Coastguard Worker; USE_BASE_32: movl %esp, %ebx 21*9880d681SAndroid Build Coastguard Worker; 22*9880d681SAndroid Build Coastguard Worker; Make sure the base pointer is saved before the RBX argument for 23*9880d681SAndroid Build Coastguard Worker; cmpxchg16b is set. 24*9880d681SAndroid Build Coastguard Worker; 25*9880d681SAndroid Build Coastguard Worker; Because of how the test is written, we spill SAVE_RBX. 26*9880d681SAndroid Build Coastguard Worker; However, it would have been perfectly fine to just keep it in register. 27*9880d681SAndroid Build Coastguard Worker; USE_BASE: movq %rbx, [[SAVE_RBX_SLOT:[0-9]*\(%[er]bx\)]] 28*9880d681SAndroid Build Coastguard Worker; 29*9880d681SAndroid Build Coastguard Worker; SAVE_RBX must be in register before we clobber rbx. 30*9880d681SAndroid Build Coastguard Worker; It is fine to use any register but rbx and the ones defined and use 31*9880d681SAndroid Build Coastguard Worker; by cmpxchg. Since such regex would be complicated to write, just stick 32*9880d681SAndroid Build Coastguard Worker; to the numbered registers. The bottom line is: if this test case fails 33*9880d681SAndroid Build Coastguard Worker; because of that regex, this is likely just the regex being too conservative. 34*9880d681SAndroid Build Coastguard Worker; USE_BASE: movq [[SAVE_RBX_SLOT]], [[SAVE_RBX:%r[0-9]+]] 35*9880d681SAndroid Build Coastguard Worker; 36*9880d681SAndroid Build Coastguard Worker; USE_BASE: movq {{[^ ]+}}, %rbx 37*9880d681SAndroid Build Coastguard Worker; USE_BASE-NEXT: cmpxchg16b 38*9880d681SAndroid Build Coastguard Worker; USE_BASE-NEXT: movq [[SAVE_RBX]], %rbx 39*9880d681SAndroid Build Coastguard Worker; 40*9880d681SAndroid Build Coastguard Worker; DONT_USE_BASE-NOT: movq %rsp, %rbx 41*9880d681SAndroid Build Coastguard Worker; DONT_USE_BASE-NOT: movl %esp, %ebx 42*9880d681SAndroid Build Coastguard Worker; DONT_USE_BASE: cmpxchg 43*9880d681SAndroid Build Coastguard Workerdefine i1 @cmp_and_swap16(i128 %a, i128 %b, i128* %addr, i32 %n) { 44*9880d681SAndroid Build Coastguard Worker %dummy = alloca i32, i32 %n 45*9880d681SAndroid Build Coastguard Workertail call void asm sideeffect "nop", "~{rax},~{rcx},~{rdx},~{rsi},~{rdi},~{rbp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15}"() 46*9880d681SAndroid Build Coastguard Worker %cmp = cmpxchg i128* %addr, i128 %a, i128 %b seq_cst seq_cst 47*9880d681SAndroid Build Coastguard Worker %res = extractvalue { i128, i1 } %cmp, 1 48*9880d681SAndroid Build Coastguard Worker %idx = getelementptr i32, i32* %dummy, i32 5 49*9880d681SAndroid Build Coastguard Worker store i32 %n, i32* %idx 50*9880d681SAndroid Build Coastguard Worker ret i1 %res 51*9880d681SAndroid Build Coastguard Worker} 52