diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp index 11dd05c584983..af5616e3e434c 100644 --- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp +++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp @@ -669,6 +669,8 @@ bool X86LegalizerInfo::legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI, return legalizeSITOFP(MI, MRI, Helper); case TargetOpcode::G_FPTOSI: return legalizeFPTOSI(MI, MRI, Helper); + case TargetOpcode::G_BITCAST: + return legalizeBitcast(MI, MRI, Helper); } llvm_unreachable("expected switch to return"); } @@ -835,6 +837,22 @@ bool X86LegalizerInfo::legalizeNarrowingStore(MachineInstr &MI, return true; } +bool X86LegalizerInfo::legalizeBitcast(MachineInstr &MI, + MachineRegisterInfo &MRI, + LegalizerHelper &Helper) const { + MachineIRBuilder &MIRBuilder = Helper.MIRBuilder; + auto [DstReg, DstTy, SrcReg, SrcTy] = MI.getFirst2RegLLTs(); + bool isCopy = + (SrcTy == DstTy) || (SrcTy.getSizeInBits() == DstTy.getSizeInBits()); + if (isCopy) { + MIRBuilder.buildCopy(DstReg, SrcReg); + MI.eraseFromParent(); + return true; + } + // For Vectors specific bitcasts + return Helper.lowerBitcast(MI) == LegalizerHelper::LegalizeResult::Legalized; +} + bool X86LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper, MachineInstr &MI) const { return true; diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h index 1ba82674ed4c6..eb42126d079fb 100644 --- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h +++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.h @@ -54,6 +54,8 @@ class X86LegalizerInfo : public LegalizerInfo { bool legalizeFPTOSI(MachineInstr &MI, MachineRegisterInfo &MRI, LegalizerHelper &Helper) const; + bool legalizeBitcast(MachineInstr &MI, MachineRegisterInfo &MRI, + LegalizerHelper &Helper) const; }; } // namespace llvm #endif diff --git a/llvm/test/CodeGen/X86/bitcast.ll b/llvm/test/CodeGen/X86/bitcast.ll index 0866a0b1b2bd1..c9193fed0ed5c 100644 --- a/llvm/test/CodeGen/X86/bitcast.ll +++ b/llvm/test/CodeGen/X86/bitcast.ll @@ -1,24 +1,57 @@ -; RUN: llc < %s -mtriple=i686-- -; RUN: llc < %s -mtriple=x86_64-- +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc < %s -mtriple=i686-- | FileCheck %s -check-prefixes=X86 +; RUN: llc < %s -mtriple=x86_64--| FileCheck %s -check-prefixes=X64 +; RUN: llc < %s -mtriple=i686-- -global-isel -global-isel-abort=0 | FileCheck %s -check-prefixes=X86 +; RUN: llc < %s -mtriple=x86_64-- -global-isel -global-isel-abort=1 | FileCheck %s -check-prefixes=X64 ; PR1033 define i64 @test1(double %t) { +; X64-LABEL: test1: +; X64: # %bb.0: +; X64-NEXT: movq %xmm0, %rax +; X64-NEXT: retq %u = bitcast double %t to i64 ; [#uses=1] ret i64 %u } define double @test2(i64 %t) { +; X86-LABEL: test2: +; X86: # %bb.0: +; X86-NEXT: fldl {{[0-9]+}}(%esp) +; X86-NEXT: retl +; +; X64-LABEL: test2: +; X64: # %bb.0: +; X64-NEXT: movq %rdi, %xmm0 +; X64-NEXT: retq %u = bitcast i64 %t to double ; [#uses=1] ret double %u } define i32 @test3(float %t) { +; X86-LABEL: test3: +; X86: # %bb.0: +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: retl +; +; X64-LABEL: test3: +; X64: # %bb.0: +; X64-NEXT: movd %xmm0, %eax +; X64-NEXT: retq %u = bitcast float %t to i32 ; [#uses=1] ret i32 %u } define float @test4(i32 %t) { +; X86-LABEL: test4: +; X86: # %bb.0: +; X86-NEXT: flds {{[0-9]+}}(%esp) +; X86-NEXT: retl +; +; X64-LABEL: test4: +; X64: # %bb.0: +; X64-NEXT: movd %edi, %xmm0 +; X64-NEXT: retq %u = bitcast i32 %t to float ; [#uses=1] ret float %u } -