[llvm] r283937 - GlobalISel: support selection of extend operations.
Quentin Colombet via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 11 21:16:10 PDT 2016
Hi Tim,
I was adding the support for copies and bit casts (we stepped a bit on each other toes, sorry about that x)) and that led me to refactor a bit the handling of G_ANYEXT. (r283972)
I wanted to point out that I was surprised that G_ANYEXT is handled differently than G_SEXT and G_ZEXT. I would have expected G_ANYEXT to be a shrunk version of the cheapest expansion of both for the related types.
What do you think?
Although, I notice that we unconditionally generate BFM-like instructions for G_SEXT and G_ZEXT. That is correct but it seems sub-optimal to me. Is the intent to use G_ANYEXT every time we know we don’t need to generate BFM or is this a limitation in the current handling?
Thanks,
-Quentin
> On Oct 11, 2016, at 1:50 PM, Tim Northover via llvm-commits <llvm-commits at lists.llvm.org> wrote:
>
> Author: tnorthover
> Date: Tue Oct 11 15:50:21 2016
> New Revision: 283937
>
> URL: http://llvm.org/viewvc/llvm-project?rev=283937&view=rev
> Log:
> GlobalISel: support selection of extend operations.
>
> Patch mostly by Ahmed Bougaca.
>
> Modified:
> llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp
> llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir
>
> Modified: llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp?rev=283937&r1=283936&r2=283937&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp (original)
> +++ llvm/trunk/lib/Target/AArch64/AArch64InstructionSelector.cpp Tue Oct 11 15:50:21 2016
> @@ -394,6 +394,105 @@ bool AArch64InstructionSelector::select(
> // operands to use appropriate classes.
> return constrainSelectedInstRegOperands(I, TII, TRI, RBI);
> }
> +
> + case TargetOpcode::G_ANYEXT: {
> + const unsigned DstReg = I.getOperand(0).getReg();
> + const unsigned SrcReg = I.getOperand(1).getReg();
> +
> + const RegisterBank &RB = *RBI.getRegBank(DstReg, MRI, TRI);
> +
> + if (RB.getID() != AArch64::GPRRegBankID) {
> + DEBUG(dbgs() << "G_ANYEXT on bank: " << RB << ", expected: GPR\n");
> + return false;
> + }
> +
> + const unsigned DstSize = MRI.getType(DstReg).getSizeInBits();
> +
> + if (DstSize == 0) {
> + DEBUG(dbgs() << "G_ANYEXT operand has no size, not a gvreg?\n");
> + return false;
> + }
> +
> + const TargetRegisterClass *RC = nullptr;
> + if (DstSize <= 32) {
> + RC = &AArch64::GPR32RegClass;
> + } else if (DstSize == 64) {
> + RC = &AArch64::GPR64RegClass;
> + } else {
> + DEBUG(dbgs() << "G_ANYEXT to size: " << DstSize
> + << ", expected: 32 or 64\n");
> + return false;
> + }
> +
> + if (!RBI.constrainGenericRegister(SrcReg, *RC, MRI) ||
> + !RBI.constrainGenericRegister(DstReg, *RC, MRI)) {
> + DEBUG(dbgs() << "Failed to constrain G_ANYEXT\n");
> + return false;
> + }
> +
> + BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::COPY))
> + .addDef(DstReg)
> + .addUse(SrcReg);
> +
> + I.eraseFromParent();
> + return true;
> + }
> +
> + case TargetOpcode::G_ZEXT:
> + case TargetOpcode::G_SEXT: {
> + unsigned Opcode = I.getOpcode();
> + const LLT DstTy = MRI.getType(I.getOperand(0).getReg()),
> + SrcTy = MRI.getType(I.getOperand(1).getReg());
> + const bool isSigned = Opcode == TargetOpcode::G_SEXT;
> + const unsigned DefReg = I.getOperand(0).getReg();
> + const unsigned SrcReg = I.getOperand(1).getReg();
> + const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
> +
> + if (RB.getID() != AArch64::GPRRegBankID) {
> + DEBUG(dbgs() << TII.getName(I.getOpcode()) << " on bank: " << RB
> + << ", expected: GPR\n");
> + return false;
> + }
> +
> + MachineInstr *ExtI;
> + if (DstTy == LLT::scalar(64)) {
> + // FIXME: Can we avoid manually doing this?
> + if (!RBI.constrainGenericRegister(SrcReg, AArch64::GPR32RegClass, MRI)) {
> + DEBUG(dbgs() << "Failed to constrain " << TII.getName(Opcode)
> + << " operand\n");
> + return false;
> + }
> +
> + const unsigned SrcXReg =
> + MRI.createVirtualRegister(&AArch64::GPR64RegClass);
> + BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::SUBREG_TO_REG))
> + .addDef(SrcXReg)
> + .addImm(0)
> + .addUse(SrcReg)
> + .addImm(AArch64::sub_32);
> +
> + const unsigned NewOpc = isSigned ? AArch64::SBFMXri : AArch64::UBFMXri;
> + ExtI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc))
> + .addDef(DefReg)
> + .addUse(SrcXReg)
> + .addImm(0)
> + .addImm(SrcTy.getSizeInBits() - 1);
> + } else if (DstTy == LLT::scalar(32)) {
> + const unsigned NewOpc = isSigned ? AArch64::SBFMWri : AArch64::UBFMWri;
> + ExtI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc))
> + .addDef(DefReg)
> + .addUse(SrcReg)
> + .addImm(0)
> + .addImm(SrcTy.getSizeInBits() - 1);
> + } else {
> + return false;
> + }
> +
> + constrainSelectedInstRegOperands(*ExtI, TII, TRI, RBI);
> +
> + I.eraseFromParent();
> + return true;
> + }
> }
>
> return false;
>
> Modified: llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir?rev=283937&r1=283936&r2=283937&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir (original)
> +++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir Tue Oct 11 15:50:21 2016
> @@ -82,6 +82,10 @@
>
> @var_got = external global i8
> define i8* @global_got() { ret i8* undef }
> +
> + define void @anyext_gpr() { ret void }
> + define void @zext_gpr() { ret void }
> + define void @sext_gpr() { ret void }
> ...
>
> ---
> @@ -1319,3 +1323,103 @@ body: |
> bb.0:
> %0(p0) = G_GLOBAL_VALUE @var_got
> ...
> +
> +---
> +# CHECK-LABEL: name: anyext_gpr
> +name: anyext_gpr
> +legalized: true
> +regBankSelected: true
> +
> +# CHECK: registers:
> +# CHECK-NEXT: - { id: 0, class: gpr64 }
> +# CHECK-NEXT: - { id: 1, class: gpr64 }
> +# CHECK-NEXT: - { id: 2, class: gpr32 }
> +# CHECK-NEXT: - { id: 3, class: gpr32 }
> +registers:
> + - { id: 0, class: gpr }
> + - { id: 1, class: gpr }
> + - { id: 2, class: gpr }
> + - { id: 3, class: gpr }
> +
> +# CHECK: body:
> +# CHECK: %0 = COPY %w0
> +# CHECK: %1 = COPY %0
> +# CHECK: %2 = COPY %w0
> +# CHECK: %3 = COPY %2
> +body: |
> + bb.0:
> + liveins: %x0
> +
> + %0(s32) = COPY %w0
> + %1(s64) = G_ANYEXT %0
> + %2(s8) = COPY %w0
> + %3(s32) = G_ANYEXT %2
> +...
> +
> +---
> +# CHECK-LABEL: name: zext_gpr
> +name: zext_gpr
> +legalized: true
> +regBankSelected: true
> +
> +# CHECK: registers:
> +# CHECK-NEXT: - { id: 0, class: gpr32 }
> +# CHECK-NEXT: - { id: 1, class: gpr64 }
> +# CHECK-NEXT: - { id: 2, class: gpr32 }
> +# CHECK-NEXT: - { id: 3, class: gpr32 }
> +# CHECK-NEXT: - { id: 4, class: gpr64 }
> +registers:
> + - { id: 0, class: gpr }
> + - { id: 1, class: gpr }
> + - { id: 2, class: gpr }
> + - { id: 3, class: gpr }
> +
> +# CHECK: body:
> +# CHECK: %0 = COPY %w0
> +# CHECK: %4 = SUBREG_TO_REG 0, %0, 15
> +# CHECK: %1 = UBFMXri %4, 0, 31
> +# CHECK: %2 = COPY %w0
> +# CHECK: %3 = UBFMWri %2, 0, 7
> +body: |
> + bb.0:
> + liveins: %x0
> +
> + %0(s32) = COPY %w0
> + %1(s64) = G_ZEXT %0
> + %2(s8) = COPY %w0
> + %3(s32) = G_ZEXT %2
> +...
> +
> +---
> +# CHECK-LABEL: name: sext_gpr
> +name: sext_gpr
> +legalized: true
> +regBankSelected: true
> +
> +# CHECK: registers:
> +# CHECK-NEXT: - { id: 0, class: gpr32 }
> +# CHECK-NEXT: - { id: 1, class: gpr64 }
> +# CHECK-NEXT: - { id: 2, class: gpr32 }
> +# CHECK-NEXT: - { id: 3, class: gpr32 }
> +# CHECK-NEXT: - { id: 4, class: gpr64 }
> +registers:
> + - { id: 0, class: gpr }
> + - { id: 1, class: gpr }
> + - { id: 2, class: gpr }
> + - { id: 3, class: gpr }
> +
> +# CHECK: body:
> +# CHECK: %0 = COPY %w0
> +# CHECK: %4 = SUBREG_TO_REG 0, %0, 15
> +# CHECK: %1 = SBFMXri %4, 0, 31
> +# CHECK: %2 = COPY %w0
> +# CHECK: %3 = SBFMWri %2, 0, 7
> +body: |
> + bb.0:
> + liveins: %x0
> +
> + %0(s32) = COPY %w0
> + %1(s64) = G_SEXT %0
> + %2(s8) = COPY %w0
> + %3(s32) = G_SEXT %2
> +...
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list