[llvm] r262759 - [X86] Do not use cmpxchgXXb when we need the base pointer (RBX).

Quentin Colombet via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 4 15:29:39 PST 2016


Author: qcolombet
Date: Fri Mar  4 17:29:39 2016
New Revision: 262759

URL: http://llvm.org/viewvc/llvm-project?rev=262759&view=rev
Log:
[X86] Do not use cmpxchgXXb when we need the base pointer (RBX).
cmpxchgXXb uses RBX as one of its implicit argument. I.e., when
we use that instruction we need to clobber RBX. This is generally
fine, expect when RBX is a reserved register because in that case,
the register allocator will not track its value and will not
save and restore it when interferences occur.

rdar://problem/24851412

Added:
    llvm/trunk/test/CodeGen/X86/base-pointer-and-cmpxchg.ll
Modified:
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=262759&r1=262758&r2=262759&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Mar  4 17:29:39 2016
@@ -21162,6 +21162,15 @@ void X86TargetLowering::ReplaceNodeResul
                                    Results);
   }
   case ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS: {
+    // If the current function needs the base pointer, RBX,
+    // we shouldn't use cmpxchg.
+    // Indeed the lowering of that instruction will clobber
+    // that register and since RBX will be a reserved register
+    // the register allocator will not make sure its value will
+    // be properly saved and restored around this live-range.
+    const X86RegisterInfo *TRI = Subtarget.getRegisterInfo();
+    if (TRI->hasBasePointer(DAG.getMachineFunction()))
+      return;
     EVT T = N->getValueType(0);
     assert((T == MVT::i64 || T == MVT::i128) && "can only expand cmpxchg pair");
     bool Regs64bit = T == MVT::i128;

Added: llvm/trunk/test/CodeGen/X86/base-pointer-and-cmpxchg.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/base-pointer-and-cmpxchg.ll?rev=262759&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/base-pointer-and-cmpxchg.ll (added)
+++ llvm/trunk/test/CodeGen/X86/base-pointer-and-cmpxchg.ll Fri Mar  4 17:29:39 2016
@@ -0,0 +1,29 @@
+; RUN: llc -mattr=+cx16 -x86-use-base-pointer=true -stackrealign -stack-alignment=32  %s -o - | FileCheck --check-prefix=CHECK --check-prefix=USE_BASE %s
+; RUN: llc -mattr=+cx16 -x86-use-base-pointer=false -stackrealign -stack-alignment=32  %s -o - | FileCheck --check-prefix=CHECK --check-prefix=DONT_USE_BASE %s
+
+; This function uses dynamic allocated stack to force the use
+; of a frame pointer.
+; The inline asm clobbers a bunch of registers to make sure
+; the frame pointer will need to be used (for spilling in that case).
+;
+; Then, we check that when we use rbx as the base pointer,
+; we do not use cmpxchg, since using that instruction requires
+; to clobbers rbx to set the arguments of the instruction and when
+; rbx is used as the base pointer, RA cannot fix the code for us.
+;
+; CHECK-LABEL: cmp_and_swap16:
+; Check that we actually use rbx.
+; USE_BASE: movq %rsp, %rbx
+; USE_BASE-NOT: cmpxchg
+;
+; DONT_USE_BASE-NOT: movq %rsp, %rbx
+; DONT_USE_BASE: cmpxchg
+define i1 @cmp_and_swap16(i128 %a, i128 %b, i128* %addr, i32 %n) {
+  %dummy = alloca i32, i32 %n
+tail call void asm sideeffect "nop", "~{rax},~{rcx},~{rdx},~{rsi},~{rdi},~{rbp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15}"()
+  %cmp = cmpxchg i128* %addr, i128 %a, i128 %b seq_cst seq_cst
+  %res = extractvalue { i128, i1 } %cmp, 1
+  %idx = getelementptr i32, i32* %dummy, i32 5
+  store i32 %n, i32* %idx
+  ret i1 %res
+}




More information about the llvm-commits mailing list