diff --git a/llvm/lib/Target/X86/X86FastISel.cpp b/llvm/lib/Target/X86/X86FastISel.cpp --- a/llvm/lib/Target/X86/X86FastISel.cpp +++ b/llvm/lib/Target/X86/X86FastISel.cpp @@ -3842,6 +3842,31 @@ return X86MaterializeFP(CFP, VT); else if (const GlobalValue *GV = dyn_cast(C)) return X86MaterializeGV(GV, VT); + else if (isa(C)) { + unsigned Opc = 0; + switch (VT.SimpleTy) { + default: + break; + case MVT::f32: + if (!X86ScalarSSEf32) + Opc = X86::LD_Fp032; + break; + case MVT::f64: + if (!X86ScalarSSEf64) + Opc = X86::LD_Fp064; + break; + case MVT::f80: + Opc = X86::LD_Fp080; + break; + } + + if (Opc) { + Register ResultReg = createResultReg(TLI.getRegClassFor(VT)); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), + ResultReg); + return ResultReg; + } + } return 0; } diff --git a/llvm/test/CodeGen/X86/fast-isel-undef-fp.ll b/llvm/test/CodeGen/X86/fast-isel-undef-fp.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/X86/fast-isel-undef-fp.ll @@ -0,0 +1,51 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc %s -o - -verify-machineinstrs -fast-isel=true -mattr=-sse | FileCheck %s + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define dso_local x86_fp80 @test_f80() { +; CHECK-LABEL: test_f80: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fldz +; CHECK-NEXT: fchs +; CHECK-NEXT: retq +entry: + %fneg1 = fneg contract x86_fp80 undef + br label %exit + +exit: ; preds = %entry + ret x86_fp80 %fneg1 +} + +define dso_local void @test_f32(float *%p) { +; CHECK-LABEL: test_f32: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fldz +; CHECK-NEXT: fchs +; CHECK-NEXT: fstps (%rdi) +; CHECK-NEXT: retq +entry: + %fneg1 = fneg contract float undef + br label %exit + +exit: ; preds = %entry + store float %fneg1, float *%p + ret void +} + +define dso_local void @test_f64(double *%p) { +; CHECK-LABEL: test_f64: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: fldz +; CHECK-NEXT: fchs +; CHECK-NEXT: fstpl (%rdi) +; CHECK-NEXT: retq +entry: + %fneg1 = fneg contract double undef + br label %exit + +exit: ; preds = %entry + store double %fneg1, double *%p + ret void +}