Index: lib/Target/X86/X86FixupSetCC.cpp =================================================================== --- lib/Target/X86/X86FixupSetCC.cpp +++ lib/Target/X86/X86FixupSetCC.cpp @@ -50,6 +50,7 @@ // Return true if MI imp-uses eflags. bool impUsesFlags(MachineInstr *MI); + bool usesAllGR32_ABCD(const MachineInstr *) const; // Return true if this is the opcode of a SetCC instruction with a register // output. @@ -57,6 +58,7 @@ MachineRegisterInfo *MRI; const X86InstrInfo *TII; + const X86RegisterInfo *TRI; enum { SearchBound = 16 }; @@ -116,10 +118,31 @@ return false; } +bool X86FixupSetCCPass::usesAllGR32_ABCD(const MachineInstr *mi) const { + BitVector gr32abcd(TRI->getNumRegs()); + gr32abcd.set(X86::EAX); + gr32abcd.set(X86::EBX); + gr32abcd.set(X86::ECX); + gr32abcd.set(X86::EDX); + + for (const MachineOperand &op : mi->operands()) { + if (op.isReg() && !TRI->isVirtualRegister(op.getReg()) && op.getReg() && + (op.isDef() || op.isUse() || op.isImplicit())) { + for (MCRegAliasIterator reg(op.getReg(), TRI, true); reg.isValid(); + ++reg) { + gr32abcd.reset(*reg); + } + } + } + + return gr32abcd.none(); +} + bool X86FixupSetCCPass::runOnMachineFunction(MachineFunction &MF) { bool Changed = false; MRI = &MF.getRegInfo(); TII = MF.getSubtarget().getInstrInfo(); + TRI = MF.getSubtarget().getRegisterInfo(); SmallVector ToErase; @@ -142,7 +165,8 @@ // Find the preceding instruction that imp-defs eflags. MachineInstr *FlagsDefMI = findFlagsImpDef( MI.getParent(), MachineBasicBlock::reverse_iterator(&MI)); - if (!FlagsDefMI) + if (!FlagsDefMI || (!MF.getSubtarget().is64Bit() && + usesAllGR32_ABCD(FlagsDefMI))) continue; // We'd like to put something that clobbers eflags directly before Index: test/CodeGen/X86/no-fixup-setcc.ll =================================================================== --- /dev/null +++ test/CodeGen/X86/no-fixup-setcc.ll @@ -0,0 +1,13 @@ +; RUN: llc < %s -O0 -march=x86 -o - | FileCheck %s + +define i1 @f(i64*, i64, i64) { +; CHECK-LABEL: f +; CHECK: cmpxchg8b +; CHECK-NEXT: sete +; CHECK-NEXT: movzbl + %a = cmpxchg i64* %0, i64 %1, i64 %2 seq_cst seq_cst + %b = extractvalue { i64, i1 } %a, 1 + %c = zext i1 %b to i32 + call void asm sideeffect "", "r"(i32 %c) + ret i1 %b +}