[X86] Fix latent bugs in 32-bit CMPXCHG8B inserter

I found three issues:
1. the loop over E[ABCD]X copies run over BB start
2. the direct address of cmpxchg8b could be a frame index
3. the displacement of cmpxchg8b could be a global instead of an
   immediate

These were all introduced together in r287875, and should be fixed with
this change.

Issue reported by Zachary Turner.

llvm-svn: 371678
This commit is contained in:
Reid Kleckner 2019-09-11 21:56:17 +00:00
parent ed5f452645
commit ff45955fc8
3 changed files with 72 additions and 7 deletions

View File

@ -31592,10 +31592,14 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
// After X86TargetLowering::ReplaceNodeResults CMPXCHG8B is glued to its
// four operand definitions that are E[ABCD] registers. We skip them and
// then insert the LEA.
MachineBasicBlock::iterator MBBI(MI);
while (MBBI->definesRegister(X86::EAX) || MBBI->definesRegister(X86::EBX) ||
MBBI->definesRegister(X86::ECX) || MBBI->definesRegister(X86::EDX))
--MBBI;
MachineBasicBlock::reverse_iterator RMBBI(MI.getReverseIterator());
while (RMBBI != BB->rend() && (RMBBI->definesRegister(X86::EAX) ||
RMBBI->definesRegister(X86::EBX) ||
RMBBI->definesRegister(X86::ECX) ||
RMBBI->definesRegister(X86::EDX))) {
++RMBBI;
}
MachineBasicBlock::iterator MBBI(RMBBI);
addFullAddress(
BuildMI(*BB, *MBBI, DL, TII->get(X86::LEA32r), computedAddrVReg), AM);

View File

@ -131,11 +131,11 @@ addDirectMem(const MachineInstrBuilder &MIB, unsigned Reg) {
/// reference.
static inline void setDirectAddressInInstr(MachineInstr *MI, unsigned Operand,
unsigned Reg) {
// Direct memory address is in a form of: Reg, 1 (Scale), NoReg, 0, NoReg.
MI->getOperand(Operand).setReg(Reg);
// Direct memory address is in a form of: Reg/FI, 1 (Scale), NoReg, 0, NoReg.
MI->getOperand(Operand).ChangeToRegister(Reg, /*isDef=*/false);
MI->getOperand(Operand + 1).setImm(1);
MI->getOperand(Operand + 2).setReg(0);
MI->getOperand(Operand + 3).setImm(0);
MI->getOperand(Operand + 3).ChangeToImmediate(0);
MI->getOperand(Operand + 4).setReg(0);
}

View File

@ -33,3 +33,64 @@ define void @foo_alloca_direct_address(i64* %addr, i32 %n) {
; CHECK-LABEL: foo_alloca_direct_address
; CHECK-NOT: leal {{\(%e.*\)}}, [[REGISTER:%e.i]]
; CHECK: lock cmpxchg8b ([[REGISTER]])
; We used to have a bug when combining:
; - base pointer for stack frame (VLA + alignment)
; - cmpxchg8b frameindex + index reg
declare void @escape(i32*)
define void @foo_alloca_index(i32 %i, i64 %val) {
entry:
%Counters = alloca [19 x i64], align 32
%vla = alloca i32, i32 %i
call void @escape(i32* %vla)
br label %body
body:
%p = getelementptr inbounds [19 x i64], [19 x i64]* %Counters, i32 0, i32 %i
%t2 = cmpxchg volatile i64* %p, i64 %val, i64 %val seq_cst seq_cst
%t3 = extractvalue { i64, i1 } %t2, 0
%cmp.i = icmp eq i64 %val, %t3
br i1 %cmp.i, label %done, label %body
done:
ret void
}
; Check that we add a LEA
; CHECK-LABEL: foo_alloca_index:
; CHECK: leal {{[0-9]*\(%e..,%e..,8\), %e..}}
; CHECK: lock cmpxchg8b ({{%e..}})
; We used to have a bug when combining:
; - base pointer for stack frame (VLA + alignment)
; - cmpxchg8b global + index reg
@Counters = external global [19 x i64]
define void @foo_alloca_index_global(i32 %i, i64 %val) {
entry:
%aligner = alloca i32, align 32
call void @escape(i32* %aligner)
%vla = alloca i32, i32 %i
call void @escape(i32* %vla)
br label %body
body:
%p = getelementptr inbounds [19 x i64], [19 x i64]* @Counters, i32 0, i32 %i
%t2 = cmpxchg volatile i64* %p, i64 %val, i64 %val seq_cst seq_cst
%t3 = extractvalue { i64, i1 } %t2, 0
%cmp.i = icmp eq i64 %val, %t3
br i1 %cmp.i, label %done, label %body
done:
ret void
}
; Check that we add a LEA
; CHECK-LABEL: foo_alloca_index_global:
; CHECK: leal {{Counters\(,%e..,8\), %e..}}
; CHECK: lock cmpxchg8b ({{%e..}})