diff --git a/llvm/lib/Target/X86/X86ExpandPseudo.cpp b/llvm/lib/Target/X86/X86ExpandPseudo.cpp --- a/llvm/lib/Target/X86/X86ExpandPseudo.cpp +++ b/llvm/lib/Target/X86/X86ExpandPseudo.cpp @@ -334,7 +334,6 @@ MBB.erase(MBBI); return true; } - case X86::LCMPXCHG8B_SAVE_EBX: case X86::LCMPXCHG16B_SAVE_RBX: { // Perform the following transformation. // SaveRbx = pseudocmpxchg Addr, <4 opds for the address>, InArg, SaveRbx @@ -345,21 +344,16 @@ const MachineOperand &InArg = MBBI->getOperand(6); Register SaveRbx = MBBI->getOperand(7).getReg(); - unsigned ActualInArg = - Opcode == X86::LCMPXCHG8B_SAVE_EBX ? X86::EBX : X86::RBX; // Copy the input argument of the pseudo into the argument of the // actual instruction. - TII->copyPhysReg(MBB, MBBI, DL, ActualInArg, InArg.getReg(), - InArg.isKill()); + TII->copyPhysReg(MBB, MBBI, DL, X86::RBX, InArg.getReg(), InArg.isKill()); // Create the actual instruction. - unsigned ActualOpc = - Opcode == X86::LCMPXCHG8B_SAVE_EBX ? X86::LCMPXCHG8B : X86::LCMPXCHG16B; - MachineInstr *NewInstr = BuildMI(MBB, MBBI, DL, TII->get(ActualOpc)); + MachineInstr *NewInstr = BuildMI(MBB, MBBI, DL, TII->get(X86::LCMPXCHG16B)); // Copy the operands related to the address. for (unsigned Idx = 1; Idx < 6; ++Idx) NewInstr->addOperand(MBBI->getOperand(Idx)); // Finally, restore the value of RBX. - TII->copyPhysReg(MBB, MBBI, DL, ActualInArg, SaveRbx, + TII->copyPhysReg(MBB, MBBI, DL, X86::RBX, SaveRbx, /*SrcIsKill*/ true); // Delete the pseudo. diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -30494,23 +30494,15 @@ MachineMemOperand *MMO = cast(N)->getMemOperand(); if (TRI->hasBasePointer(DAG.getMachineFunction()) && (BasePtr == X86::RBX || BasePtr == X86::EBX)) { - // ISel prefers the LCMPXCHG64 variant. - // If that assert breaks, that means it is not the case anymore, - // and we need to teach LCMPXCHG8_SAVE_EBX_DAG how to save RBX, - // not just EBX. This is a matter of accepting i64 input for that - // pseudo, and restoring into the register of the right wide - // in expand pseudo. Everything else should just work. - assert(((Regs64bit == (BasePtr == X86::RBX)) || BasePtr == X86::EBX) && - "Saving only half of the RBX"); - unsigned Opcode = Regs64bit ? X86ISD::LCMPXCHG16_SAVE_RBX_DAG - : X86ISD::LCMPXCHG8_SAVE_EBX_DAG; + assert(Regs64bit && "RBX/EBX base pointer only expected for i128 CAS"); SDValue RBXSave = DAG.getCopyFromReg(swapInH.getValue(0), dl, - Regs64bit ? X86::RBX : X86::EBX, + X86::RBX, HalfT, swapInH.getValue(1)); SDValue Ops[] = {/*Chain*/ RBXSave.getValue(1), N->getOperand(1), swapInL, RBXSave, /*Glue*/ RBXSave.getValue(2)}; - Result = DAG.getMemIntrinsicNode(Opcode, dl, Tys, Ops, T, MMO); + Result = DAG.getMemIntrinsicNode(X86ISD::LCMPXCHG16_SAVE_RBX_DAG, dl, Tys, + Ops, T, MMO); } else { unsigned Opcode = Regs64bit ? X86ISD::LCMPXCHG16_DAG : X86ISD::LCMPXCHG8_DAG; @@ -33780,12 +33772,9 @@ } case X86::LCMPXCHG16B: return BB; - case X86::LCMPXCHG8B_SAVE_EBX: case X86::LCMPXCHG16B_SAVE_RBX: { - unsigned BasePtr = - MI.getOpcode() == X86::LCMPXCHG8B_SAVE_EBX ? X86::EBX : X86::RBX; - if (!BB->isLiveIn(BasePtr)) - BB->addLiveIn(BasePtr); + if (!BB->isLiveIn(X86::RBX)) + BB->addLiveIn(X86::RBX); return BB; } case X86::MWAITX: { diff --git a/llvm/lib/Target/X86/X86InstrCompiler.td b/llvm/lib/Target/X86/X86InstrCompiler.td --- a/llvm/lib/Target/X86/X86InstrCompiler.td +++ b/llvm/lib/Target/X86/X86InstrCompiler.td @@ -845,6 +845,12 @@ defm LCMPXCHG8B : LCMPXCHG_UnOp<0xC7, MRM1m, "cmpxchg8b", X86cas8, i64mem>; } +let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX], + Predicates = [HasCmpxchg16b,In64BitMode], SchedRW = [WriteCMPXCHGRMW] in { +defm LCMPXCHG16B : LCMPXCHG_UnOp<0xC7, MRM1m, "cmpxchg16b", + X86cas16, i128mem>, REX_W; +} + // This pseudo must be used when the frame uses RBX as // the base pointer. Indeed, in such situation RBX is a reserved // register and the register allocator will ignore any use/def of @@ -852,38 +858,18 @@ // RBX that will happen when setting the arguments for the instrucion. // // Unlike the actual related instruction, we mark that this one -// defines EBX (instead of using EBX). +// defines RBX (instead of using RBX). // The rationale is that we will define RBX during the expansion of -// the pseudo. The argument feeding EBX is ebx_input. +// the pseudo. The argument feeding RBX is rbx_input. // -// The additional argument, $ebx_save, is a temporary register used to +// The additional argument, $rbx_save, is a temporary register used to // save the value of RBX across the actual instruction. // -// To make sure the register assigned to $ebx_save does not interfere with +// To make sure the register assigned to $rbx_save does not interfere with // the definition of the actual instruction, we use a definition $dst which // is tied to $rbx_save. That way, the live-range of $rbx_save spans across // the instruction and we are sure we will have a valid register to restore // the value of RBX. -let Defs = [EAX, EDX, EBX, EFLAGS], Uses = [EAX, ECX, EDX], - Predicates = [HasCmpxchg8b], SchedRW = [WriteCMPXCHGRMW], - isCodeGenOnly = 1, isPseudo = 1, Constraints = "$ebx_save = $dst", - usesCustomInserter = 1 in { -def LCMPXCHG8B_SAVE_EBX : - I<0, Pseudo, (outs GR32:$dst), - (ins i64mem:$ptr, GR32:$ebx_input, GR32:$ebx_save), - !strconcat("cmpxchg8b", "\t$ptr"), - [(set GR32:$dst, (X86cas8save_ebx addr:$ptr, GR32:$ebx_input, - GR32:$ebx_save))]>; -} - - -let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX], - Predicates = [HasCmpxchg16b,In64BitMode], SchedRW = [WriteCMPXCHGRMW] in { -defm LCMPXCHG16B : LCMPXCHG_UnOp<0xC7, MRM1m, "cmpxchg16b", - X86cas16, i128mem>, REX_W; -} - -// Same as LCMPXCHG8B_SAVE_RBX but for the 16 Bytes variant. let Defs = [RAX, RDX, RBX, EFLAGS], Uses = [RAX, RCX, RDX], Predicates = [HasCmpxchg16b,In64BitMode], SchedRW = [WriteCMPXCHGRMW], isCodeGenOnly = 1, isPseudo = 1, Constraints = "$rbx_save = $dst", diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -70,9 +70,6 @@ def SDTX86cas : SDTypeProfile<0, 3, [SDTCisPtrTy<0>, SDTCisInt<1>, SDTCisVT<2, i8>]>; def SDTX86caspair : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>; -def SDTX86caspairSaveEbx8 : SDTypeProfile<1, 3, - [SDTCisVT<0, i32>, SDTCisPtrTy<1>, - SDTCisVT<2, i32>, SDTCisVT<3, i32>]>; def SDTX86caspairSaveRbx16 : SDTypeProfile<1, 3, [SDTCisVT<0, i64>, SDTCisPtrTy<1>, SDTCisVT<2, i64>, SDTCisVT<3, i64>]>; @@ -180,10 +177,6 @@ def X86cas16 : SDNode<"X86ISD::LCMPXCHG16_DAG", SDTX86caspair, [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; -def X86cas8save_ebx : SDNode<"X86ISD::LCMPXCHG8_SAVE_EBX_DAG", - SDTX86caspairSaveEbx8, - [SDNPHasChain, SDNPInGlue, SDNPOutGlue, - SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; def X86cas16save_rbx : SDNode<"X86ISD::LCMPXCHG16_SAVE_RBX_DAG", SDTX86caspairSaveRbx16, [SDNPHasChain, SDNPInGlue, SDNPOutGlue,