Skip to content

Commit 4da4e7c

Browse files
committed
[X86] Remove X86ISD::LCMPXCHG8_SAVE_EBX_DAG and LCMPXCHG8B_SAVE_EBX pseudo instruction
This and its friend X86ISD::LCMPXCHG8_SAVE_RBX_DAG are used if we need to avoid clobbering the frame pointer in EBX/RBX. EBX/RBX are only used a frame pointer in 64-bit mode. In 64-bit mode we don't use CMPXCHG8B since we have a GR64 cmpxchg available. So we don't need special handling for LCMPXCHG8B. Split from D88808 Differential Revision: https://reviews.llvm.org/D88853
1 parent 1127662 commit 4da4e7c

File tree

4 files changed

+19
-57
lines changed

4 files changed

+19
-57
lines changed

llvm/lib/Target/X86/X86ExpandPseudo.cpp

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,6 @@ bool X86ExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
334334
MBB.erase(MBBI);
335335
return true;
336336
}
337-
case X86::LCMPXCHG8B_SAVE_EBX:
338337
case X86::LCMPXCHG16B_SAVE_RBX: {
339338
// Perform the following transformation.
340339
// SaveRbx = pseudocmpxchg Addr, <4 opds for the address>, InArg, SaveRbx
@@ -345,21 +344,16 @@ bool X86ExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
345344
const MachineOperand &InArg = MBBI->getOperand(6);
346345
Register SaveRbx = MBBI->getOperand(7).getReg();
347346

348-
unsigned ActualInArg =
349-
Opcode == X86::LCMPXCHG8B_SAVE_EBX ? X86::EBX : X86::RBX;
350347
// Copy the input argument of the pseudo into the argument of the
351348
// actual instruction.
352-
TII->copyPhysReg(MBB, MBBI, DL, ActualInArg, InArg.getReg(),
353-
InArg.isKill());
349+
TII->copyPhysReg(MBB, MBBI, DL, X86::RBX, InArg.getReg(), InArg.isKill());
354350
// Create the actual instruction.
355-
unsigned ActualOpc =
356-
Opcode == X86::LCMPXCHG8B_SAVE_EBX ? X86::LCMPXCHG8B : X86::LCMPXCHG16B;
357-
MachineInstr *NewInstr = BuildMI(MBB, MBBI, DL, TII->get(ActualOpc));
351+
MachineInstr *NewInstr = BuildMI(MBB, MBBI, DL, TII->get(X86::LCMPXCHG16B));
358352
// Copy the operands related to the address.
359353
for (unsigned Idx = 1; Idx < 6; ++Idx)
360354
NewInstr->addOperand(MBBI->getOperand(Idx));
361355
// Finally, restore the value of RBX.
362-
TII->copyPhysReg(MBB, MBBI, DL, ActualInArg, SaveRbx,
356+
TII->copyPhysReg(MBB, MBBI, DL, X86::RBX, SaveRbx,
363357
/*SrcIsKill*/ true);
364358

365359
// Delete the pseudo.

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30494,23 +30494,15 @@ void X86TargetLowering::ReplaceNodeResults(SDNode *N,
3049430494
MachineMemOperand *MMO = cast<AtomicSDNode>(N)->getMemOperand();
3049530495
if (TRI->hasBasePointer(DAG.getMachineFunction()) &&
3049630496
(BasePtr == X86::RBX || BasePtr == X86::EBX)) {
30497-
// ISel prefers the LCMPXCHG64 variant.
30498-
// If that assert breaks, that means it is not the case anymore,
30499-
// and we need to teach LCMPXCHG8_SAVE_EBX_DAG how to save RBX,
30500-
// not just EBX. This is a matter of accepting i64 input for that
30501-
// pseudo, and restoring into the register of the right wide
30502-
// in expand pseudo. Everything else should just work.
30503-
assert(((Regs64bit == (BasePtr == X86::RBX)) || BasePtr == X86::EBX) &&
30504-
"Saving only half of the RBX");
30505-
unsigned Opcode = Regs64bit ? X86ISD::LCMPXCHG16_SAVE_RBX_DAG
30506-
: X86ISD::LCMPXCHG8_SAVE_EBX_DAG;
30497+
assert(Regs64bit && "RBX/EBX base pointer only expected for i128 CAS");
3050730498
SDValue RBXSave = DAG.getCopyFromReg(swapInH.getValue(0), dl,
30508-
Regs64bit ? X86::RBX : X86::EBX,
30499+
X86::RBX,
3050930500
HalfT, swapInH.getValue(1));
3051030501
SDValue Ops[] = {/*Chain*/ RBXSave.getValue(1), N->getOperand(1), swapInL,
3051130502
RBXSave,
3051230503
/*Glue*/ RBXSave.getValue(2)};
30513-
Result = DAG.getMemIntrinsicNode(Opcode, dl, Tys, Ops, T, MMO);
30504+
Result = DAG.getMemIntrinsicNode(X86ISD::LCMPXCHG16_SAVE_RBX_DAG, dl, Tys,
30505+
Ops, T, MMO);
3051430506
} else {
3051530507
unsigned Opcode =
3051630508
Regs64bit ? X86ISD::LCMPXCHG16_DAG : X86ISD::LCMPXCHG8_DAG;
@@ -33780,12 +33772,9 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
3378033772
}
3378133773
case X86::LCMPXCHG16B:
3378233774
return BB;
33783-
case X86::LCMPXCHG8B_SAVE_EBX:
3378433775
case X86::LCMPXCHG16B_SAVE_RBX: {
33785-
unsigned BasePtr =
33786-
MI.getOpcode() == X86::LCMPXCHG8B_SAVE_EBX ? X86::EBX : X86::RBX;
33787-
if (!BB->isLiveIn(BasePtr))
33788-
BB->addLiveIn(BasePtr);
33776+
if (!BB->isLiveIn(X86::RBX))
33777+
BB->addLiveIn(X86::RBX);
3378933778
return BB;
3379033779
}
3379133780
case X86::MWAITX: {

llvm/lib/Target/X86/X86InstrCompiler.td

Lines changed: 10 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -845,45 +845,31 @@ let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX],
845845
defm LCMPXCHG8B : LCMPXCHG_UnOp<0xC7, MRM1m, "cmpxchg8b", X86cas8, i64mem>;
846846
}
847847

848+
let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX],
849+
Predicates = [HasCmpxchg16b,In64BitMode], SchedRW = [WriteCMPXCHGRMW] in {
850+
defm LCMPXCHG16B : LCMPXCHG_UnOp<0xC7, MRM1m, "cmpxchg16b",
851+
X86cas16, i128mem>, REX_W;
852+
}
853+
848854
// This pseudo must be used when the frame uses RBX as
849855
// the base pointer. Indeed, in such situation RBX is a reserved
850856
// register and the register allocator will ignore any use/def of
851857
// it. In other words, the register will not fix the clobbering of
852858
// RBX that will happen when setting the arguments for the instrucion.
853859
//
854860
// Unlike the actual related instruction, we mark that this one
855-
// defines EBX (instead of using EBX).
861+
// defines RBX (instead of using RBX).
856862
// The rationale is that we will define RBX during the expansion of
857-
// the pseudo. The argument feeding EBX is ebx_input.
863+
// the pseudo. The argument feeding RBX is rbx_input.
858864
//
859-
// The additional argument, $ebx_save, is a temporary register used to
865+
// The additional argument, $rbx_save, is a temporary register used to
860866
// save the value of RBX across the actual instruction.
861867
//
862-
// To make sure the register assigned to $ebx_save does not interfere with
868+
// To make sure the register assigned to $rbx_save does not interfere with
863869
// the definition of the actual instruction, we use a definition $dst which
864870
// is tied to $rbx_save. That way, the live-range of $rbx_save spans across
865871
// the instruction and we are sure we will have a valid register to restore
866872
// the value of RBX.
867-
let Defs = [EAX, EDX, EBX, EFLAGS], Uses = [EAX, ECX, EDX],
868-
Predicates = [HasCmpxchg8b], SchedRW = [WriteCMPXCHGRMW],
869-
isCodeGenOnly = 1, isPseudo = 1, Constraints = "$ebx_save = $dst",
870-
usesCustomInserter = 1 in {
871-
def LCMPXCHG8B_SAVE_EBX :
872-
I<0, Pseudo, (outs GR32:$dst),
873-
(ins i64mem:$ptr, GR32:$ebx_input, GR32:$ebx_save),
874-
!strconcat("cmpxchg8b", "\t$ptr"),
875-
[(set GR32:$dst, (X86cas8save_ebx addr:$ptr, GR32:$ebx_input,
876-
GR32:$ebx_save))]>;
877-
}
878-
879-
880-
let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX],
881-
Predicates = [HasCmpxchg16b,In64BitMode], SchedRW = [WriteCMPXCHGRMW] in {
882-
defm LCMPXCHG16B : LCMPXCHG_UnOp<0xC7, MRM1m, "cmpxchg16b",
883-
X86cas16, i128mem>, REX_W;
884-
}
885-
886-
// Same as LCMPXCHG8B_SAVE_RBX but for the 16 Bytes variant.
887873
let Defs = [RAX, RDX, RBX, EFLAGS], Uses = [RAX, RCX, RDX],
888874
Predicates = [HasCmpxchg16b,In64BitMode], SchedRW = [WriteCMPXCHGRMW],
889875
isCodeGenOnly = 1, isPseudo = 1, Constraints = "$rbx_save = $dst",

llvm/lib/Target/X86/X86InstrInfo.td

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,6 @@ def SDTX86wrpkru : SDTypeProfile<0, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
7070
def SDTX86cas : SDTypeProfile<0, 3, [SDTCisPtrTy<0>, SDTCisInt<1>,
7171
SDTCisVT<2, i8>]>;
7272
def SDTX86caspair : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
73-
def SDTX86caspairSaveEbx8 : SDTypeProfile<1, 3,
74-
[SDTCisVT<0, i32>, SDTCisPtrTy<1>,
75-
SDTCisVT<2, i32>, SDTCisVT<3, i32>]>;
7673
def SDTX86caspairSaveRbx16 : SDTypeProfile<1, 3,
7774
[SDTCisVT<0, i64>, SDTCisPtrTy<1>,
7875
SDTCisVT<2, i64>, SDTCisVT<3, i64>]>;
@@ -180,10 +177,6 @@ def X86cas8 : SDNode<"X86ISD::LCMPXCHG8_DAG", SDTX86caspair,
180177
def X86cas16 : SDNode<"X86ISD::LCMPXCHG16_DAG", SDTX86caspair,
181178
[SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore,
182179
SDNPMayLoad, SDNPMemOperand]>;
183-
def X86cas8save_ebx : SDNode<"X86ISD::LCMPXCHG8_SAVE_EBX_DAG",
184-
SDTX86caspairSaveEbx8,
185-
[SDNPHasChain, SDNPInGlue, SDNPOutGlue,
186-
SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>;
187180
def X86cas16save_rbx : SDNode<"X86ISD::LCMPXCHG16_SAVE_RBX_DAG",
188181
SDTX86caspairSaveRbx16,
189182
[SDNPHasChain, SDNPInGlue, SDNPOutGlue,

0 commit comments

Comments
 (0)