diff options
| author | Tim Northover <tnorthover@apple.com> | 2016-10-18 20:03:48 +0000 |
|---|---|---|
| committer | Tim Northover <tnorthover@apple.com> | 2016-10-18 20:03:48 +0000 |
| commit | 55782222c0500de1dea1aeee40e1fdf31dc853eb (patch) | |
| tree | 0ffeedf67baf97c57caeba2c375d3bb38744ce39 | |
| parent | 3f18603c522c80b67db57a42bda01c6525d1acc2 (diff) | |
| download | bcm5719-llvm-55782222c0500de1dea1aeee40e1fdf31dc853eb.tar.gz bcm5719-llvm-55782222c0500de1dea1aeee40e1fdf31dc853eb.zip | |
GlobalISel: select small binary operations on AArch64.
AArch64 actually supports many 8-bit operations under the definition used by
GlobalISel: the designated information-carrying bits of a GPR32 get the right
value if you just use the normal 32-bit instruction.
llvm-svn: 284526
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp | 13 | ||||
| -rw-r--r-- | llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir | 407 |
2 files changed, 416 insertions, 4 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp index ebfd78ba2b2..eb2614d482c 100644 --- a/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp @@ -123,8 +123,13 @@ static unsigned selectBinaryOp(unsigned GenericOpc, unsigned RegBankID, unsigned OpSize) { switch (RegBankID) { case AArch64::GPRRegBankID: - switch (OpSize) { - case 32: + if (OpSize <= 32) { + assert((OpSize == 32 || (GenericOpc != TargetOpcode::G_SDIV && + GenericOpc != TargetOpcode::G_UDIV && + GenericOpc != TargetOpcode::G_LSHR && + GenericOpc != TargetOpcode::G_ASHR)) && + "operation should have been legalized before now"); + switch (GenericOpc) { case TargetOpcode::G_OR: return AArch64::ORRWrr; @@ -149,7 +154,7 @@ static unsigned selectBinaryOp(unsigned GenericOpc, unsigned RegBankID, default: return GenericOpc; } - case 64: + } else if (OpSize == 64) { switch (GenericOpc) { case TargetOpcode::G_OR: return AArch64::ORRXrr; @@ -676,7 +681,7 @@ bool AArch64InstructionSelector::select(MachineInstr &I) const { unsigned ZeroReg; unsigned NewOpc; - if (Ty == LLT::scalar(32)) { + if (Ty.isScalar() && Ty.getSizeInBits() <= 32) { NewOpc = AArch64::MADDWrrr; ZeroReg = AArch64::WZR; } else if (Ty == LLT::scalar(64)) { diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir index 6ea29f04e6b..a86c0659610 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-instructionselect.mir @@ -8,22 +8,34 @@ --- | target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" + define void @add_s8_gpr() { ret void } + define void @add_s16_gpr() { ret void } define void @add_s32_gpr() { ret void } define void @add_s64_gpr() { ret void } + define void @sub_s8_gpr() { ret void } + define void @sub_s16_gpr() { ret void } define void @sub_s32_gpr() { ret void } define void @sub_s64_gpr() { ret void } + define void @or_s1_gpr() { ret void } + define void @or_s16_gpr() { ret void } define void @or_s32_gpr() { ret void } define void @or_s64_gpr() { ret void } define void @or_v2s32_fpr() { ret void } + define void @xor_s8_gpr() { ret void } + define void @xor_s16_gpr() { ret void } define void @xor_s32_gpr() { ret void } define void @xor_s64_gpr() { ret void } + define void @and_s8_gpr() { ret void } + define void @and_s16_gpr() { ret void } define void @and_s32_gpr() { ret void } define void @and_s64_gpr() { ret void } + define void @shl_s8_gpr() { ret void } + define void @shl_s16_gpr() { ret void } define void @shl_s32_gpr() { ret void } define void @shl_s64_gpr() { ret void } @@ -33,6 +45,8 @@ define void @ashr_s32_gpr() { ret void } define void @ashr_s64_gpr() { ret void } + define void @mul_s8_gpr() { ret void } + define void @mul_s16_gpr() { ret void } define void @mul_s32_gpr() { ret void } define void @mul_s64_gpr() { ret void } @@ -136,6 +150,62 @@ ... --- +# CHECK-LABEL: name: add_s8_gpr +name: add_s8_gpr +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: gpr32 } +# CHECK-NEXT: - { id: 1, class: gpr32 } +# CHECK-NEXT: - { id: 2, class: gpr32 } +registers: + - { id: 0, class: gpr } + - { id: 1, class: gpr } + - { id: 2, class: gpr } + +# CHECK: body: +# CHECK: %0 = COPY %w0 +# CHECK: %1 = COPY %w1 +# CHECK: %2 = ADDWrr %0, %1 +body: | + bb.0: + liveins: %w0, %w1 + + %0(s8) = COPY %w0 + %1(s8) = COPY %w1 + %2(s8) = G_ADD %0, %1 +... + +--- +# CHECK-LABEL: name: add_s16_gpr +name: add_s16_gpr +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: gpr32 } +# CHECK-NEXT: - { id: 1, class: gpr32 } +# CHECK-NEXT: - { id: 2, class: gpr32 } +registers: + - { id: 0, class: gpr } + - { id: 1, class: gpr } + - { id: 2, class: gpr } + +# CHECK: body: +# CHECK: %0 = COPY %w0 +# CHECK: %1 = COPY %w1 +# CHECK: %2 = ADDWrr %0, %1 +body: | + bb.0: + liveins: %w0, %w1 + + %0(s16) = COPY %w0 + %1(s16) = COPY %w1 + %2(s16) = G_ADD %0, %1 +... + +--- # Check that we select a 32-bit GPR G_ADD into ADDWrr on GPR32. # Also check that we constrain the register class of the COPY to GPR32. # CHECK-LABEL: name: add_s32_gpr @@ -195,6 +265,62 @@ body: | ... --- +# CHECK-LABEL: name: sub_s8_gpr +name: sub_s8_gpr +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: gpr32 } +# CHECK-NEXT: - { id: 1, class: gpr32 } +# CHECK-NEXT: - { id: 2, class: gpr32 } +registers: + - { id: 0, class: gpr } + - { id: 1, class: gpr } + - { id: 2, class: gpr } + +# CHECK: body: +# CHECK: %0 = COPY %w0 +# CHECK: %1 = COPY %w1 +# CHECK: %2 = SUBWrr %0, %1 +body: | + bb.0: + liveins: %w0, %w1 + + %0(s8) = COPY %w0 + %1(s8) = COPY %w1 + %2(s8) = G_SUB %0, %1 +... + +--- +# CHECK-LABEL: name: sub_s16_gpr +name: sub_s16_gpr +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: gpr32 } +# CHECK-NEXT: - { id: 1, class: gpr32 } +# CHECK-NEXT: - { id: 2, class: gpr32 } +registers: + - { id: 0, class: gpr } + - { id: 1, class: gpr } + - { id: 2, class: gpr } + +# CHECK: body: +# CHECK: %0 = COPY %w0 +# CHECK: %1 = COPY %w1 +# CHECK: %2 = SUBWrr %0, %1 +body: | + bb.0: + liveins: %w0, %w1 + + %0(s16) = COPY %w0 + %1(s16) = COPY %w1 + %2(s16) = G_SUB %0, %1 +... + +--- # Same as add_s32_gpr, for G_SUB operations. # CHECK-LABEL: name: sub_s32_gpr name: sub_s32_gpr @@ -253,6 +379,62 @@ body: | ... --- +# CHECK-LABEL: name: or_s1_gpr +name: or_s1_gpr +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: gpr32 } +# CHECK-NEXT: - { id: 1, class: gpr32 } +# CHECK-NEXT: - { id: 2, class: gpr32 } +registers: + - { id: 0, class: gpr } + - { id: 1, class: gpr } + - { id: 2, class: gpr } + +# CHECK: body: +# CHECK: %0 = COPY %w0 +# CHECK: %1 = COPY %w1 +# CHECK: %2 = ORRWrr %0, %1 +body: | + bb.0: + liveins: %w0, %w1 + + %0(s1) = COPY %w0 + %1(s1) = COPY %w1 + %2(s1) = G_OR %0, %1 +... + +--- +# CHECK-LABEL: name: or_s16_gpr +name: or_s16_gpr +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: gpr32 } +# CHECK-NEXT: - { id: 1, class: gpr32 } +# CHECK-NEXT: - { id: 2, class: gpr32 } +registers: + - { id: 0, class: gpr } + - { id: 1, class: gpr } + - { id: 2, class: gpr } + +# CHECK: body: +# CHECK: %0 = COPY %w0 +# CHECK: %1 = COPY %w1 +# CHECK: %2 = ORRWrr %0, %1 +body: | + bb.0: + liveins: %w0, %w1 + + %0(s16) = COPY %w0 + %1(s16) = COPY %w1 + %2(s16) = G_OR %0, %1 +... + +--- # Same as add_s32_gpr, for G_OR operations. # CHECK-LABEL: name: or_s32_gpr name: or_s32_gpr @@ -342,6 +524,62 @@ body: | ... --- +# CHECK-LABEL: name: xor_s8_gpr +name: xor_s8_gpr +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: gpr32 } +# CHECK-NEXT: - { id: 1, class: gpr32 } +# CHECK-NEXT: - { id: 2, class: gpr32 } +registers: + - { id: 0, class: gpr } + - { id: 1, class: gpr } + - { id: 2, class: gpr } + +# CHECK: body: +# CHECK: %0 = COPY %w0 +# CHECK: %1 = COPY %w1 +# CHECK: %2 = EORWrr %0, %1 +body: | + bb.0: + liveins: %w0, %w1 + + %0(s8) = COPY %w0 + %1(s8) = COPY %w1 + %2(s8) = G_XOR %0, %1 +... + +--- +# CHECK-LABEL: name: xor_s16_gpr +name: xor_s16_gpr +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: gpr32 } +# CHECK-NEXT: - { id: 1, class: gpr32 } +# CHECK-NEXT: - { id: 2, class: gpr32 } +registers: + - { id: 0, class: gpr } + - { id: 1, class: gpr } + - { id: 2, class: gpr } + +# CHECK: body: +# CHECK: %0 = COPY %w0 +# CHECK: %1 = COPY %w1 +# CHECK: %2 = EORWrr %0, %1 +body: | + bb.0: + liveins: %w0, %w1 + + %0(s16) = COPY %w0 + %1(s16) = COPY %w1 + %2(s16) = G_XOR %0, %1 +... + +--- # Same as add_s32_gpr, for G_XOR operations. # CHECK-LABEL: name: xor_s32_gpr name: xor_s32_gpr @@ -400,6 +638,62 @@ body: | ... --- +# CHECK-LABEL: name: and_s8_gpr +name: and_s8_gpr +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: gpr32 } +# CHECK-NEXT: - { id: 1, class: gpr32 } +# CHECK-NEXT: - { id: 2, class: gpr32 } +registers: + - { id: 0, class: gpr } + - { id: 1, class: gpr } + - { id: 2, class: gpr } + +# CHECK: body: +# CHECK: %0 = COPY %w0 +# CHECK: %1 = COPY %w1 +# CHECK: %2 = ANDWrr %0, %1 +body: | + bb.0: + liveins: %w0, %w1 + + %0(s8) = COPY %w0 + %1(s8) = COPY %w1 + %2(s8) = G_AND %0, %1 +... + +--- +# CHECK-LABEL: name: and_s16_gpr +name: and_s16_gpr +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: gpr32 } +# CHECK-NEXT: - { id: 1, class: gpr32 } +# CHECK-NEXT: - { id: 2, class: gpr32 } +registers: + - { id: 0, class: gpr } + - { id: 1, class: gpr } + - { id: 2, class: gpr } + +# CHECK: body: +# CHECK: %0 = COPY %w0 +# CHECK: %1 = COPY %w1 +# CHECK: %2 = ANDWrr %0, %1 +body: | + bb.0: + liveins: %w0, %w1 + + %0(s16) = COPY %w0 + %1(s16) = COPY %w1 + %2(s16) = G_AND %0, %1 +... + +--- # Same as add_s32_gpr, for G_AND operations. # CHECK-LABEL: name: and_s32_gpr name: and_s32_gpr @@ -458,6 +752,62 @@ body: | ... --- +# CHECK-LABEL: name: shl_s8_gpr +name: shl_s8_gpr +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: gpr32 } +# CHECK-NEXT: - { id: 1, class: gpr32 } +# CHECK-NEXT: - { id: 2, class: gpr32 } +registers: + - { id: 0, class: gpr } + - { id: 1, class: gpr } + - { id: 2, class: gpr } + +# CHECK: body: +# CHECK: %0 = COPY %w0 +# CHECK: %1 = COPY %w1 +# CHECK: %2 = LSLVWr %0, %1 +body: | + bb.0: + liveins: %w0, %w1 + + %0(s8) = COPY %w0 + %1(s8) = COPY %w1 + %2(s8) = G_SHL %0, %1 +... + +--- +# CHECK-LABEL: name: shl_s16_gpr +name: shl_s16_gpr +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: gpr32 } +# CHECK-NEXT: - { id: 1, class: gpr32 } +# CHECK-NEXT: - { id: 2, class: gpr32 } +registers: + - { id: 0, class: gpr } + - { id: 1, class: gpr } + - { id: 2, class: gpr } + +# CHECK: body: +# CHECK: %0 = COPY %w0 +# CHECK: %1 = COPY %w1 +# CHECK: %2 = LSLVWr %0, %1 +body: | + bb.0: + liveins: %w0, %w1 + + %0(s16) = COPY %w0 + %1(s16) = COPY %w1 + %2(s16) = G_SHL %0, %1 +... + +--- # Same as add_s32_gpr, for G_SHL operations. # CHECK-LABEL: name: shl_s32_gpr name: shl_s32_gpr @@ -631,6 +981,63 @@ body: | %2(s64) = G_ASHR %0, %1 ... +--- +# CHECK-LABEL: name: mul_s8_gpr +name: mul_s8_gpr +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: gpr32 } +# CHECK-NEXT: - { id: 1, class: gpr32 } +# CHECK-NEXT: - { id: 2, class: gpr32 } +registers: + - { id: 0, class: gpr } + - { id: 1, class: gpr } + - { id: 2, class: gpr } + +# CHECK: body: +# CHECK: %0 = COPY %w0 +# CHECK: %1 = COPY %w1 +# CHECK: %2 = MADDWrrr %0, %1, %wzr +body: | + bb.0: + liveins: %w0, %w1 + + %0(s8) = COPY %w0 + %1(s8) = COPY %w1 + %2(s8) = G_MUL %0, %1 +... + +--- +# CHECK-LABEL: name: mul_s16_gpr +name: mul_s16_gpr +legalized: true +regBankSelected: true + +# CHECK: registers: +# CHECK-NEXT: - { id: 0, class: gpr32 } +# CHECK-NEXT: - { id: 1, class: gpr32 } +# CHECK-NEXT: - { id: 2, class: gpr32 } +registers: + - { id: 0, class: gpr } + - { id: 1, class: gpr } + - { id: 2, class: gpr } + +# CHECK: body: +# CHECK: %0 = COPY %w0 +# CHECK: %1 = COPY %w1 +# CHECK: %2 = MADDWrrr %0, %1, %wzr +body: | + bb.0: + liveins: %w0, %w1 + + %0(s16) = COPY %w0 + %1(s16) = COPY %w1 + %2(s16) = G_MUL %0, %1 +... + +--- # Check that we select s32 GPR G_MUL. This is trickier than other binops because # there is only MADDWrrr, and we have to use the WZR physreg. # CHECK-LABEL: name: mul_s32_gpr |

