Index: lib/Target/X86/X86LegalizerInfo.cpp =================================================================== --- lib/Target/X86/X86LegalizerInfo.cpp +++ lib/Target/X86/X86LegalizerInfo.cpp @@ -184,6 +184,7 @@ if (!Subtarget.hasSSE2()) return; + const LLT s32 = LLT::scalar(32); const LLT s64 = LLT::scalar(64); const LLT v16s8 = LLT::vector(16, 8); const LLT v8s16 = LLT::vector(8, 16); @@ -199,6 +200,9 @@ setAction({BinOp, Ty}, Legal); setAction({G_MUL, v8s16}, Legal); + + setAction({G_FPEXT, s64}, Legal); + setAction({G_FPEXT, 1, s32}, Legal); } void X86LegalizerInfo::setLegalizerInfoSSE41() { Index: lib/Target/X86/X86RegisterBankInfo.cpp =================================================================== --- lib/Target/X86/X86RegisterBankInfo.cpp +++ lib/Target/X86/X86RegisterBankInfo.cpp @@ -186,10 +186,17 @@ } unsigned NumOperands = MI.getNumOperands(); - - // Track the bank of each register, use NotFP mapping (all scalars in GPRs) SmallVector OpRegBankIdx(NumOperands); - getInstrPartialMappingIdxs(MI, MRI, /* isFP */ false, OpRegBankIdx); + + switch (Opc) { + case TargetOpcode::G_FPEXT: + getInstrPartialMappingIdxs(MI, MRI, /* isFP */ true, OpRegBankIdx); + break; + default: + // Track the bank of each register, use NotFP mapping (all scalars in GPRs) + getInstrPartialMappingIdxs(MI, MRI, /* isFP */ false, OpRegBankIdx); + break; + } // Finally construct the computed mapping. SmallVector OpdsMapping(NumOperands); Index: test/CodeGen/X86/GlobalISel/fpext-scalar.ll =================================================================== --- /dev/null +++ test/CodeGen/X86/GlobalISel/fpext-scalar.ll @@ -0,0 +1,12 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=x86_64-linux-gnu -global-isel -verify-machineinstrs < %s -o - | FileCheck %s --check-prefix=CHECK + +define double @test(float %a) { +; CHECK-LABEL: test: +; CHECK: # BB#0: # %entry +; CHECK-NEXT: cvtss2sd %xmm0, %xmm0 +; CHECK-NEXT: retq +entry: + %conv = fpext float %a to double + ret double %conv +} Index: test/CodeGen/X86/GlobalISel/legalize-fpext-scalar.mir =================================================================== --- /dev/null +++ test/CodeGen/X86/GlobalISel/legalize-fpext-scalar.mir @@ -0,0 +1,33 @@ +# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=legalizer %s -o - | FileCheck %s --check-prefix=ALL +--- | + + define double @test(float %a) { + entry: + %conv = fpext float %a to double + ret double %conv + } + +... +--- +name: test +# ALL-LABEL: name: test +alignment: 4 +legalized: false +regBankSelected: false +registers: + - { id: 0, class: _, preferred-register: '' } + - { id: 1, class: _, preferred-register: '' } +# ALL: %0(s32) = COPY %xmm0 +# ALL-NEXT: %1(s64) = G_FPEXT %0(s32) +# ALL-NEXT: %xmm0 = COPY %1(s64) +# ALL-NEXT: RET 0, implicit %xmm0 +body: | + bb.1.entry: + liveins: %xmm0 + + %0(s32) = COPY %xmm0 + %1(s64) = G_FPEXT %0(s32) + %xmm0 = COPY %1(s64) + RET 0, implicit %xmm0 + +... Index: test/CodeGen/X86/GlobalISel/regbankselect-X86_64.mir =================================================================== --- test/CodeGen/X86/GlobalISel/regbankselect-X86_64.mir +++ test/CodeGen/X86/GlobalISel/regbankselect-X86_64.mir @@ -174,6 +174,12 @@ ret i64 %ret } + define double @test_fpext(float %a) { + entry: + %conv = fpext float %a to double + ret double %conv + } + ... --- name: test_add_i8 @@ -1084,4 +1090,26 @@ RET 0, implicit %rax ... +--- +name: test_fpext +# CHECK-LABEL: name: test_fpext +alignment: 4 +legalized: true +regBankSelected: false +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: vecr, preferred-register: '' } +# CHECK-NEXT: - { id: 1, class: vecr, preferred-register: '' } +registers: + - { id: 0, class: _, preferred-register: '' } + - { id: 1, class: _, preferred-register: '' } +body: | + bb.1.entry: + liveins: %xmm0 + + %0(s32) = COPY %xmm0 + %1(s64) = G_FPEXT %0(s32) + %xmm0 = COPY %1(s64) + RET 0, implicit %xmm0 + +... Index: test/CodeGen/X86/GlobalISel/select-fpext-scalar.mir =================================================================== --- /dev/null +++ test/CodeGen/X86/GlobalISel/select-fpext-scalar.mir @@ -0,0 +1,40 @@ +# RUN: llc -mtriple=x86_64-linux-gnu -global-isel -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=ALL +--- | + + define double @test(float %a) { + entry: + %conv = fpext float %a to double + ret double %conv + } + +... +--- +name: test +# ALL-LABEL: name: test +alignment: 4 +legalized: true +regBankSelected: true +# ALL: registers: +# ALL-NEXT: - { id: 0, class: fr32, preferred-register: '' } +# ALL-NEXT: - { id: 1, class: fr64, preferred-register: '' } +registers: + - { id: 0, class: vecr, preferred-register: '' } + - { id: 1, class: vecr, preferred-register: '' } +liveins: +fixedStack: +stack: +constants: +# ALL: %0 = COPY %xmm0 +# ALL-NEXT: %1 = CVTSS2SDrr %0 +# ALL-NEXT: %xmm0 = COPY %1 +# ALL-NEXT: RET 0, implicit %xmm0 +body: | + bb.1.entry: + liveins: %xmm0 + + %0(s32) = COPY %xmm0 + %1(s64) = G_FPEXT %0(s32) + %xmm0 = COPY %1(s64) + RET 0, implicit %xmm0 + +...