From: Tim Northover Date: Wed, 12 Oct 2016 22:49:11 +0000 (+0000) Subject: GlobalISel: support int <-> float conversions on AArch64. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8394d5db03ab801922cc03bdb8cba3bed282d6b9;p=llvm GlobalISel: support int <-> float conversions on AArch64. More of Ahmed's work. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@284074 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/AArch64/AArch64InstructionSelector.cpp b/lib/Target/AArch64/AArch64InstructionSelector.cpp index 84f9d4e5cfb..df4bf699f02 100644 --- a/lib/Target/AArch64/AArch64InstructionSelector.cpp +++ b/lib/Target/AArch64/AArch64InstructionSelector.cpp @@ -274,6 +274,82 @@ static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, return true; } +static unsigned selectFPConvOpc(unsigned GenericOpc, LLT DstTy, LLT SrcTy) { + if (!DstTy.isScalar() || !SrcTy.isScalar()) + return GenericOpc; + + const unsigned DstSize = DstTy.getSizeInBits(); + const unsigned SrcSize = SrcTy.getSizeInBits(); + + switch (DstSize) { + case 32: + switch (SrcSize) { + case 32: + switch (GenericOpc) { + case TargetOpcode::G_SITOFP: + return AArch64::SCVTFUWSri; + case TargetOpcode::G_UITOFP: + return AArch64::UCVTFUWSri; + case TargetOpcode::G_FPTOSI: + return AArch64::FCVTZSUWSr; + case TargetOpcode::G_FPTOUI: + return AArch64::FCVTZUUWSr; + default: + return GenericOpc; + } + case 64: + switch (GenericOpc) { + case TargetOpcode::G_SITOFP: + return AArch64::SCVTFUXSri; + case TargetOpcode::G_UITOFP: + return AArch64::UCVTFUXSri; + case TargetOpcode::G_FPTOSI: + return AArch64::FCVTZSUWDr; + case TargetOpcode::G_FPTOUI: + return AArch64::FCVTZUUWDr; + default: + return GenericOpc; + } + default: + return GenericOpc; + } + case 64: + switch (SrcSize) { + case 32: + switch (GenericOpc) { + case TargetOpcode::G_SITOFP: + return AArch64::SCVTFUWDri; + case TargetOpcode::G_UITOFP: + return AArch64::UCVTFUWDri; + case TargetOpcode::G_FPTOSI: + return AArch64::FCVTZSUXSr; + case TargetOpcode::G_FPTOUI: + return AArch64::FCVTZUUXSr; + default: + return GenericOpc; + } + case 64: + switch (GenericOpc) { + case TargetOpcode::G_SITOFP: + return AArch64::SCVTFUXDri; + case TargetOpcode::G_UITOFP: + return AArch64::UCVTFUXDri; + case TargetOpcode::G_FPTOSI: + return AArch64::FCVTZSUXDr; + case TargetOpcode::G_FPTOUI: + return AArch64::FCVTZUUXDr; + default: + return GenericOpc; + } + default: + return GenericOpc; + } + default: + return GenericOpc; + }; + return GenericOpc; +} + static AArch64CC::CondCode changeICMPPredToAArch64CC(CmpInst::Predicate P) { switch (P) { default: @@ -371,10 +447,11 @@ bool AArch64InstructionSelector::select(MachineInstr &I) const { return false; } + unsigned Opcode = I.getOpcode(); LLT Ty = I.getOperand(0).isReg() ? MRI.getType(I.getOperand(0).getReg()) : LLT{}; - switch (I.getOpcode()) { + switch (Opcode) { case TargetOpcode::G_BR: { I.setDesc(TII.get(AArch64::B)); return true; @@ -654,6 +731,23 @@ bool AArch64InstructionSelector::select(MachineInstr &I) const { return true; } + case TargetOpcode::G_SITOFP: + case TargetOpcode::G_UITOFP: + case TargetOpcode::G_FPTOSI: + case TargetOpcode::G_FPTOUI: { + const LLT DstTy = MRI.getType(I.getOperand(0).getReg()), + SrcTy = MRI.getType(I.getOperand(1).getReg()); + const unsigned NewOpc = selectFPConvOpc(Opcode, DstTy, SrcTy); + if (NewOpc == Opcode) + return false; + + I.setDesc(TII.get(NewOpc)); + constrainSelectedInstRegOperands(I, TII, TRI, RBI); + + return true; + } + + case TargetOpcode::G_INTTOPTR: case TargetOpcode::G_PTRTOINT: case TargetOpcode::G_BITCAST: diff --git a/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir b/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir index 73ac37971af..c42db8b0280 100644 --- a/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir +++ b/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir @@ -53,6 +53,26 @@ define void @fdiv_s32_gpr() { ret void } define void @fdiv_s64_gpr() { ret void } + define void @sitofp_s32_s32_fpr() { ret void } + define void @sitofp_s32_s64_fpr() { ret void } + define void @sitofp_s64_s32_fpr() { ret void } + define void @sitofp_s64_s64_fpr() { ret void } + + define void @uitofp_s32_s32_fpr() { ret void } + define void @uitofp_s32_s64_fpr() { ret void } + define void @uitofp_s64_s32_fpr() { ret void } + define void @uitofp_s64_s64_fpr() { ret void } + + define void @fptosi_s32_s32_gpr() { ret void } + define void @fptosi_s32_s64_gpr() { ret void } + define void @fptosi_s64_s32_gpr() { ret void } + define void @fptosi_s64_s64_gpr() { ret void } + + define void @fptoui_s32_s32_gpr() { ret void } + define void @fptoui_s32_s64_gpr() { ret void } + define void @fptoui_s64_s32_gpr() { ret void } + define void @fptoui_s64_s64_gpr() { ret void } + define void @unconditional_br() { ret void } define void @conditional_br() { ret void } @@ -998,6 +1018,390 @@ body: | %2(s64) = G_FDIV %0, %1 ... +--- +# CHECK-LABEL: name: sitofp_s32_s32_fpr +name: sitofp_s32_s32_fpr +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: gpr32 } +# CHECK-NEXT: - { id: 1, class: fpr32 } +registers: + - { id: 0, class: gpr } + - { id: 1, class: fpr } + +# CHECK: body: +# CHECK: %0 = COPY %w0 +# CHECK: %1 = SCVTFUWSri %0 +body: | + bb.0: + liveins: %w0 + + %0(s32) = COPY %w0 + %1(s32) = G_SITOFP %0 +... + +--- +# CHECK-LABEL: name: sitofp_s32_s64_fpr +name: sitofp_s32_s64_fpr +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: gpr64 } +# CHECK-NEXT: - { id: 1, class: fpr32 } +registers: + - { id: 0, class: gpr } + - { id: 1, class: fpr } + +# CHECK: body: +# CHECK: %0 = COPY %x0 +# CHECK: %1 = SCVTFUXSri %0 +body: | + bb.0: + liveins: %x0 + + %0(s64) = COPY %x0 + %1(s32) = G_SITOFP %0 +... + +--- +# CHECK-LABEL: name: sitofp_s64_s32_fpr +name: sitofp_s64_s32_fpr +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: gpr32 } +# CHECK-NEXT: - { id: 1, class: fpr64 } +registers: + - { id: 0, class: gpr } + - { id: 1, class: fpr } + +# CHECK: body: +# CHECK: %0 = COPY %w0 +# CHECK: %1 = SCVTFUWDri %0 +body: | + bb.0: + liveins: %w0 + + %0(s32) = COPY %w0 + %1(s64) = G_SITOFP %0 +... + +--- +# CHECK-LABEL: name: sitofp_s64_s64_fpr +name: sitofp_s64_s64_fpr +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: gpr64 } +# CHECK-NEXT: - { id: 1, class: fpr64 } +registers: + - { id: 0, class: gpr } + - { id: 1, class: fpr } + +# CHECK: body: +# CHECK: %0 = COPY %x0 +# CHECK: %1 = SCVTFUXDri %0 +body: | + bb.0: + liveins: %x0 + + %0(s64) = COPY %x0 + %1(s64) = G_SITOFP %0 +... + +--- +# CHECK-LABEL: name: uitofp_s32_s32_fpr +name: uitofp_s32_s32_fpr +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: gpr32 } +# CHECK-NEXT: - { id: 1, class: fpr32 } +registers: + - { id: 0, class: gpr } + - { id: 1, class: fpr } + +# CHECK: body: +# CHECK: %0 = COPY %w0 +# CHECK: %1 = UCVTFUWSri %0 +body: | + bb.0: + liveins: %w0 + + %0(s32) = COPY %w0 + %1(s32) = G_UITOFP %0 +... + +--- +# CHECK-LABEL: name: uitofp_s32_s64_fpr +name: uitofp_s32_s64_fpr +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: gpr64 } +# CHECK-NEXT: - { id: 1, class: fpr32 } +registers: + - { id: 0, class: gpr } + - { id: 1, class: fpr } + +# CHECK: body: +# CHECK: %0 = COPY %x0 +# CHECK: %1 = UCVTFUXSri %0 +body: | + bb.0: + liveins: %x0 + + %0(s64) = COPY %x0 + %1(s32) = G_UITOFP %0 +... + +--- +# CHECK-LABEL: name: uitofp_s64_s32_fpr +name: uitofp_s64_s32_fpr +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: gpr32 } +# CHECK-NEXT: - { id: 1, class: fpr64 } +registers: + - { id: 0, class: gpr } + - { id: 1, class: fpr } + +# CHECK: body: +# CHECK: %0 = COPY %w0 +# CHECK: %1 = UCVTFUWDri %0 +body: | + bb.0: + liveins: %w0 + + %0(s32) = COPY %w0 + %1(s64) = G_UITOFP %0 +... + +--- +# CHECK-LABEL: name: uitofp_s64_s64_fpr +name: uitofp_s64_s64_fpr +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: gpr64 } +# CHECK-NEXT: - { id: 1, class: fpr64 } +registers: + - { id: 0, class: gpr } + - { id: 1, class: fpr } + +# CHECK: body: +# CHECK: %0 = COPY %x0 +# CHECK: %1 = UCVTFUXDri %0 +body: | + bb.0: + liveins: %x0 + + %0(s64) = COPY %x0 + %1(s64) = G_UITOFP %0 +... + +--- +# CHECK-LABEL: name: fptosi_s32_s32_gpr +name: fptosi_s32_s32_gpr +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: fpr32 } +# CHECK-NEXT: - { id: 1, class: gpr32 } +registers: + - { id: 0, class: fpr } + - { id: 1, class: gpr } + +# CHECK: body: +# CHECK: %0 = COPY %s0 +# CHECK: %1 = FCVTZSUWSr %0 +body: | + bb.0: + liveins: %s0 + + %0(s32) = COPY %s0 + %1(s32) = G_FPTOSI %0 +... + +--- +# CHECK-LABEL: name: fptosi_s32_s64_gpr +name: fptosi_s32_s64_gpr +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: fpr64 } +# CHECK-NEXT: - { id: 1, class: gpr32 } +registers: + - { id: 0, class: fpr } + - { id: 1, class: gpr } + +# CHECK: body: +# CHECK: %0 = COPY %d0 +# CHECK: %1 = FCVTZSUWDr %0 +body: | + bb.0: + liveins: %d0 + + %0(s64) = COPY %d0 + %1(s32) = G_FPTOSI %0 +... + +--- +# CHECK-LABEL: name: fptosi_s64_s32_gpr +name: fptosi_s64_s32_gpr +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: fpr32 } +# CHECK-NEXT: - { id: 1, class: gpr64 } +registers: + - { id: 0, class: fpr } + - { id: 1, class: gpr } + +# CHECK: body: +# CHECK: %0 = COPY %s0 +# CHECK: %1 = FCVTZSUXSr %0 +body: | + bb.0: + liveins: %s0 + + %0(s32) = COPY %s0 + %1(s64) = G_FPTOSI %0 +... + +--- +# CHECK-LABEL: name: fptosi_s64_s64_gpr +name: fptosi_s64_s64_gpr +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: fpr64 } +# CHECK-NEXT: - { id: 1, class: gpr64 } +registers: + - { id: 0, class: fpr } + - { id: 1, class: gpr } + +# CHECK: body: +# CHECK: %0 = COPY %d0 +# CHECK: %1 = FCVTZSUXDr %0 +body: | + bb.0: + liveins: %d0 + + %0(s64) = COPY %d0 + %1(s64) = G_FPTOSI %0 +... + +--- +# CHECK-LABEL: name: fptoui_s32_s32_gpr +name: fptoui_s32_s32_gpr +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: fpr32 } +# CHECK-NEXT: - { id: 1, class: gpr32 } +registers: + - { id: 0, class: fpr } + - { id: 1, class: gpr } + +# CHECK: body: +# CHECK: %0 = COPY %s0 +# CHECK: %1 = FCVTZUUWSr %0 +body: | + bb.0: + liveins: %s0 + + %0(s32) = COPY %s0 + %1(s32) = G_FPTOUI %0 +... + +--- +# CHECK-LABEL: name: fptoui_s32_s64_gpr +name: fptoui_s32_s64_gpr +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: fpr64 } +# CHECK-NEXT: - { id: 1, class: gpr32 } +registers: + - { id: 0, class: fpr } + - { id: 1, class: gpr } + +# CHECK: body: +# CHECK: %0 = COPY %d0 +# CHECK: %1 = FCVTZUUWDr %0 +body: | + bb.0: + liveins: %d0 + + %0(s64) = COPY %d0 + %1(s32) = G_FPTOUI %0 +... + +--- +# CHECK-LABEL: name: fptoui_s64_s32_gpr +name: fptoui_s64_s32_gpr +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: fpr32 } +# CHECK-NEXT: - { id: 1, class: gpr64 } +registers: + - { id: 0, class: fpr } + - { id: 1, class: gpr } + +# CHECK: body: +# CHECK: %0 = COPY %s0 +# CHECK: %1 = FCVTZUUXSr %0 +body: | + bb.0: + liveins: %s0 + + %0(s32) = COPY %s0 + %1(s64) = G_FPTOUI %0 +... + +--- +# CHECK-LABEL: name: fptoui_s64_s64_gpr +name: fptoui_s64_s64_gpr +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: fpr64 } +# CHECK-NEXT: - { id: 1, class: gpr64 } +registers: + - { id: 0, class: fpr } + - { id: 1, class: gpr } + +# CHECK: body: +# CHECK: %0 = COPY %d0 +# CHECK: %1 = FCVTZUUXDr %0 +body: | + bb.0: + liveins: %d0 + + %0(s64) = COPY %d0 + %1(s64) = G_FPTOUI %0 +... + --- # CHECK-LABEL: name: unconditional_br name: unconditional_br