diff --git a/lib/Target/X86/X86CodeEmitter.cpp b/lib/Target/X86/X86CodeEmitter.cpp index 5d72b4469ea..0f9c562eb50 100644 --- a/lib/Target/X86/X86CodeEmitter.cpp +++ b/lib/Target/X86/X86CodeEmitter.cpp @@ -985,8 +985,14 @@ void Emitter::emitVEXOpcodePrefix(uint64_t TSFlags, if (X86II::isX86_64ExtendedReg(MI.getOperand(0).getReg())) VEX_R = 0x0; - if (HasVEX_4V) - VEX_4V = getVEXRegisterEncoding(MI, 1); + if (HasVEX_4V) { + if (HasMemOp4) + VEX_4V = getVEXRegisterEncoding(MI, 1); + else + // FMA3 instructions operands are dst, src1, src2, src3 + // dst and src1 are the same and not encoded separately + VEX_4V = getVEXRegisterEncoding(MI, 2); + } if (X86II::isX86_64ExtendedReg( MI.getOperand(MemOperand+X86::AddrBaseReg).getReg())) diff --git a/test/ExecutionEngine/fma3-jit.ll b/test/ExecutionEngine/fma3-jit.ll new file mode 100644 index 00000000000..25eaa65a538 --- /dev/null +++ b/test/ExecutionEngine/fma3-jit.ll @@ -0,0 +1,18 @@ +; RUN: %lli %s | FileCheck %s +; REQUIRES: fma3 +; CHECK: 12.000000 + +@msg_double = internal global [4 x i8] c"%f\0A\00" + +declare i32 @printf(i8*, ...) + +define i32 @main() { + %fma = tail call double @llvm.fma.f64(double 3.0, double 3.0, double 3.0) nounwind readnone + + %ptr1 = getelementptr [4 x i8]* @msg_double, i32 0, i32 0 + call i32 (i8*,...)* @printf(i8* %ptr1, double %fma) + + ret i32 0 +} + +declare double @llvm.fma.f64(double, double, double) nounwind readnone