Index: lib/Target/X86/X86ISelLowering.cpp =================================================================== --- lib/Target/X86/X86ISelLowering.cpp +++ lib/Target/X86/X86ISelLowering.cpp @@ -21016,21 +21016,42 @@ MachineRegisterInfo &MRI = BB->getParent()->getRegInfo(); unsigned MSrc = MI->getOperand(0).getReg(); unsigned VSrc = MI->getOperand(5).getReg(); - MachineInstrBuilder MIM = BuildMI(*BB, MI, DL, TII->get(MOp)) - .addReg(/*Base=*/MSrc) - .addImm(/*Scale=*/1) - .addReg(/*Index=*/0) - .addImm(0) - .addReg(0); - MachineInstr *MIO = BuildMI(*BB, (MachineInstr *)MIM, DL, TII->get(FOp), - MRI.createVirtualRegister(MRI.getRegClass(VSrc))) - .addReg(VSrc) - .addReg(/*Base=*/MSrc) - .addImm(/*Scale=*/1) - .addReg(/*Index=*/0) - .addImm(/*Disp=*/0) - .addReg(/*Segment=*/0); - MIM.addReg(MIO->getOperand(0).getReg(), RegState::Kill); + MachineOperand Disp = MI->getOperand(3); + bool hasDisp = Disp.isGlobal() || Disp.isImm(); + MachineInstr *MIO; + if (hasDisp) { + MachineInstrBuilder MIM = BuildMI(*BB, MI, DL, TII->get(MOp)) + .addReg(/*Base=*/MSrc) + .addImm(/*Scale=*/1) + .addReg(/*Index=*/0) + .addDisp(Disp, /*off=*/0) + .addReg(0); + MIO = BuildMI(*BB, (MachineInstr *)MIM, DL, TII->get(FOp), + MRI.createVirtualRegister(MRI.getRegClass(VSrc))) + .addReg(VSrc) + .addReg(/*Base=*/MSrc) + .addImm(/*Scale=*/1) + .addReg(/*Index=*/0) + .addDisp(Disp, /*off=*/0) + .addReg(/*Segment=*/0); + MIM.addReg(MIO->getOperand(0).getReg(), RegState::Kill); + } else { + MachineInstrBuilder MIM = BuildMI(*BB, MI, DL, TII->get(MOp)) + .addReg(/*Base=*/MSrc) + .addImm(/*Scale=*/1) + .addReg(/*Index=*/0) + .addImm(0) + .addReg(0); + MIO = BuildMI(*BB, (MachineInstr *)MIM, DL, TII->get(FOp), + MRI.createVirtualRegister(MRI.getRegClass(VSrc))) + .addReg(VSrc) + .addReg(/*Base=*/MSrc) + .addImm(/*Scale=*/1) + .addReg(/*Index=*/0) + .addImm(/*Disp=*/0) + .addReg(/*Segment=*/0); + MIM.addReg(MIO->getOperand(0).getReg(), RegState::Kill); + } MI->eraseFromParent(); // The pseudo instruction is gone now. return BB; } Index: test/CodeGen/X86/atomic_mi.ll =================================================================== --- test/CodeGen/X86/atomic_mi.ll +++ test/CodeGen/X86/atomic_mi.ll @@ -871,3 +871,74 @@ store atomic i64 %3, i64* %floc release, align 8 ret void } + +@glob32 = global float 0.000000e+00, align 4 +@glob64 = global double 0.000000e+00, align 8 + +; Floating-point add to a global using an immediate. +define void @fadd_32g() { +; X64-LABEL: fadd_32g: +; X64-NOT: lock +; X64: movss .{{[A-Z0-9_]+}}(%rip), %[[XMM:xmm[0-9]+]] +; X64-NEXT: addss glob32(%rip), %[[XMM]] +; X64-NEXT: movss %[[XMM]], glob32(%rip) +; X32-LABEL: fadd_32g: +; Don't check x86-32 (see comment above). + %i = load atomic i32, i32* bitcast (float* @glob32 to i32*) monotonic, align 4 + %f = bitcast i32 %i to float + %add = fadd float %f, 1.000000e+00 + %s = bitcast float %add to i32 + store atomic i32 %s, i32* bitcast (float* @glob32 to i32*) monotonic, align 4 + ret void +} + +define void @fadd_64g() { +; X64-LABEL: fadd_64g: +; X64-NOT: lock +; X64: movsd .{{[A-Z0-9_]+}}(%rip), %[[XMM:xmm[0-9]+]] +; X64-NEXT: addsd glob64(%rip), %[[XMM]] +; X64-NEXT: movsd %[[XMM]], glob64(%rip) +; X32-LABEL: fadd_64g: +; Don't check x86-32 (see comment above). + %i = load atomic i64, i64* bitcast (double* @glob64 to i64*) monotonic, align 8 + %f = bitcast i64 %i to double + %add = fadd double %f, 1.000000e+00 + %s = bitcast double %add to i64 + store atomic i64 %s, i64* bitcast (double* @glob64 to i64*) monotonic, align 8 + ret void +} + +; Floating-point add to a hard-coded immediate location using an immediate. +define void @fadd_32imm() { +; X64-LABEL: fadd_32imm: +; X64-NOT: lock +; X64: movl $3735928559, %e[[M:[a-z]+]] +; X64: movss .{{[A-Z0-9_]+}}(%rip), %[[XMM:xmm[0-9]+]] +; X64-NEXT: addss (%r[[M]]), %[[XMM]] +; X64-NEXT: movss %[[XMM]], (%r[[M]]) +; X32-LABEL: fadd_32imm: +; Don't check x86-32 (see comment above). + %i = load atomic i32, i32* inttoptr (i32 3735928559 to i32*) monotonic, align 4 + %f = bitcast i32 %i to float + %add = fadd float %f, 1.000000e+00 + %s = bitcast float %add to i32 + store atomic i32 %s, i32* inttoptr (i32 3735928559 to i32*) monotonic, align 4 + ret void +} + +define void @fadd_64imm() { +; X64-LABEL: fadd_64imm: +; X64-NOT: lock +; X64: movl $3735928559, %e[[M:[a-z]+]] +; X64: movsd .{{[A-Z0-9_]+}}(%rip), %[[XMM:xmm[0-9]+]] +; X64-NEXT: addsd (%r[[M]]), %[[XMM]] +; X64-NEXT: movsd %[[XMM]], (%r[[M]]) +; X32-LABEL: fadd_64imm: +; Don't check x86-32 (see comment above). + %i = load atomic i64, i64* inttoptr (i64 3735928559 to i64*) monotonic, align 8 + %f = bitcast i64 %i to double + %add = fadd double %f, 1.000000e+00 + %s = bitcast double %add to i64 + store atomic i64 %s, i64* inttoptr (i64 3735928559 to i64*) monotonic, align 8 + ret void +}