From 7a753d9bec529698c16475c72cf1de386b63381f Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Fri, 26 Aug 2016 17:46:06 +0000 Subject: [PATCH] GlobalISel: legalize under-width divisions. llvm-svn: 279841 --- .../CodeGen/GlobalISel/MachineLegalizeHelper.cpp | 27 ++++++++++++++ .../lib/Target/AArch64/AArch64MachineLegalizer.cpp | 8 +++-- .../CodeGen/AArch64/GlobalISel/legalize-div.mir | 42 ++++++++++++++++++++++ 3 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/legalize-div.mir diff --git a/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp b/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp index 66b7166..401f29a 100644 --- a/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp @@ -161,6 +161,33 @@ MachineLegalizeHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, MI.eraseFromParent(); return Legalized; } + case TargetOpcode::G_SDIV: + case TargetOpcode::G_UDIV: { + unsigned ExtOp = MI.getOpcode() == TargetOpcode::G_SDIV + ? TargetOpcode::G_SEXT + : TargetOpcode::G_ZEXT; + + unsigned LHSExt = MRI.createGenericVirtualRegister(WideSize); + MIRBuilder.buildInstr(ExtOp, {WideTy, MI.getType()}) + .addDef(LHSExt) + .addUse(MI.getOperand(1).getReg()); + + unsigned RHSExt = MRI.createGenericVirtualRegister(WideSize); + MIRBuilder.buildInstr(ExtOp, {WideTy, MI.getType()}) + .addDef(RHSExt) + .addUse(MI.getOperand(2).getReg()); + + unsigned ResExt = MRI.createGenericVirtualRegister(WideSize); + MIRBuilder.buildInstr(MI.getOpcode(), WideTy) + .addDef(ResExt) + .addUse(LHSExt) + .addUse(RHSExt); + + MIRBuilder.buildTrunc({MI.getType(), WideTy}, MI.getOperand(0).getReg(), + ResExt); + MI.eraseFromParent(); + return Legalized; + } case TargetOpcode::G_LOAD: { assert(alignTo(Ty.getSizeInBits(), 8) == WideSize && "illegal to increase number of bytes loaded"); diff --git a/llvm/lib/Target/AArch64/AArch64MachineLegalizer.cpp b/llvm/lib/Target/AArch64/AArch64MachineLegalizer.cpp index 1a329361..0c9addf 100644 --- a/llvm/lib/Target/AArch64/AArch64MachineLegalizer.cpp +++ b/llvm/lib/Target/AArch64/AArch64MachineLegalizer.cpp @@ -36,17 +36,21 @@ AArch64MachineLegalizer::AArch64MachineLegalizer() { const LLT v4s32 = LLT::vector(4, 32); const LLT v2s64 = LLT::vector(2, 64); - for (auto BinOp : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR}) { + for (auto BinOp : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR, G_SHL}) { // These operations naturally get the right answer when used on // GPR32, even if the actual type is narrower. for (auto Ty : {s1, s8, s16, s32, s64, v2s32, v4s32, v2s64}) setAction({BinOp, Ty}, Legal); } - for (auto BinOp : {G_SHL, G_LSHR, G_ASHR, G_SDIV, G_UDIV}) + for (auto BinOp : {G_LSHR, G_ASHR, G_SDIV, G_UDIV}) { for (auto Ty : {s32, s64}) setAction({BinOp, Ty}, Legal); + for (auto Ty : {s1, s8, s16}) + setAction({BinOp, Ty}, WidenScalar); + } + for (auto Op : { G_UADDE, G_USUBE, G_SADDO, G_SSUBO, G_SMULO, G_UMULO }) { for (auto Ty : { s32, s64 }) setAction({Op, Ty}, Legal); diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-div.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-div.mir new file mode 100644 index 0000000..ff8b5cb --- /dev/null +++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-div.mir @@ -0,0 +1,42 @@ +# RUN: llc -O0 -run-pass=legalize-mir -global-isel %s -o - 2>&1 | FileCheck %s + +--- | + target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" + target triple = "aarch64-apple-ios" + define void @test_div() { + entry: + ret void + } +... + +--- +name: test_div +registers: + - { id: 0, class: _ } + - { id: 1, class: _ } + - { id: 2, class: _ } + - { id: 3, class: _ } + - { id: 4, class: _ } + - { id: 5, class: _ } +body: | + bb.0.entry: + liveins: %x0, %x1, %x2, %x3 + %0(64) = COPY %x0 + %1(64) = COPY %x1 + %2(32) = G_TRUNC { s8, s64 } %0 + %3(32) = G_TRUNC { s8, s64 } %1 + + + ; CHECK: [[LHS32:%[0-9]+]](32) = G_SEXT { s32, s8 } %2 + ; CHECK: [[RHS32:%[0-9]+]](32) = G_SEXT { s32, s8 } %3 + ; CHECK: [[QUOT32:%[0-9]+]](32) = G_SDIV s32 [[LHS32]], [[RHS32]] + ; CHECK: [[RES:%[0-9]+]](8) = G_TRUNC { s8, s32 } [[QUOT32]] + %4(8) = G_SDIV s8 %2, %3 + + ; CHECK: [[LHS32:%[0-9]+]](32) = G_ZEXT { s32, s8 } %2 + ; CHECK: [[RHS32:%[0-9]+]](32) = G_ZEXT { s32, s8 } %3 + ; CHECK: [[QUOT32:%[0-9]+]](32) = G_UDIV s32 [[LHS32]], [[RHS32]] + ; CHECK: [[RES:%[0-9]+]](8) = G_TRUNC { s8, s32 } [[QUOT32]] + %5(8) = G_UDIV s8 %2, %3 + +... -- 2.7.4