[llvm] r279842 - GlobalISel: legalize sdiv and srem operations.
Tim Northover via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 26 10:46:13 PDT 2016
Author: tnorthover
Date: Fri Aug 26 12:46:13 2016
New Revision: 279842
URL: http://llvm.org/viewvc/llvm-project?rev=279842&view=rev
Log:
GlobalISel: legalize sdiv and srem operations.
Added:
llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-rem.mir
Modified:
llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h
llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizer.h
llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizer.cpp
llvm/trunk/lib/Target/AArch64/AArch64MachineLegalizer.cpp
llvm/trunk/unittests/CodeGen/GlobalISel/MachineLegalizerTest.cpp
Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h?rev=279842&r1=279841&r2=279842&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h Fri Aug 26 12:46:13 2016
@@ -144,6 +144,28 @@ public:
MachineInstrBuilder buildAdd(LLT Ty, unsigned Res, unsigned Op0,
unsigned Op1);
+ /// Build and insert \p Res<def> = G_SUB \p Ty \p Op0, \p Op1
+ ///
+ /// G_SUB sets \p Res to the sum of integer parameters \p Op0 and \p Op1,
+ /// truncated to their width.
+ ///
+ /// \pre setBasicBlock or setMI must have been called.
+ ///
+ /// \return a MachineInstrBuilder for the newly created instruction.
+ MachineInstrBuilder buildSub(LLT Ty, unsigned Res, unsigned Op0,
+ unsigned Op1);
+
+ /// Build and insert \p Res<def> = G_MUL \p Ty \p Op0, \p Op1
+ ///
+ /// G_MUL sets \p Res to the sum of integer parameters \p Op0 and \p Op1,
+ /// truncated to their width.
+ ///
+ /// \pre setBasicBlock or setMI must have been called.
+ ///
+ /// \return a MachineInstrBuilder for the newly created instruction.
+ MachineInstrBuilder buildMul(LLT Ty, unsigned Res, unsigned Op0,
+ unsigned Op1);
+
/// Build and insert \p Res<def>, \p CarryOut = G_UADDE \p Tys \p Op0, \p Op1,
/// \p CarryIn
///
Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h?rev=279842&r1=279841&r2=279842&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizeHelper.h Fri Aug 26 12:46:13 2016
@@ -70,6 +70,10 @@ public:
/// precision, ignoring the unused bits).
LegalizeResult widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
+ /// Legalize an instruction by splitting it into simpler parts, hopefully
+ /// understood by the target.
+ LegalizeResult lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
+
/// Legalize a vector instruction by splitting into multiple components, each
/// acting on the same scalar type as the original but with fewer elements.
LegalizeResult fewerElementsVector(MachineInstr &MI, unsigned TypeIdx,
Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizer.h?rev=279842&r1=279841&r2=279842&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizer.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizer.h Fri Aug 26 12:46:13 2016
@@ -87,6 +87,10 @@ public:
/// the first two results.
MoreElements,
+ /// The operation itself must be expressed in terms of simpler actions on
+ /// this target. E.g. a SREM replaced by an SDIV and subtraction.
+ Lower,
+
/// The operation should be implemented as a call to some kind of runtime
/// support library. For example this usually happens on machines that don't
/// support floating-point operations natively.
Modified: llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp?rev=279842&r1=279841&r2=279842&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp Fri Aug 26 12:46:13 2016
@@ -99,6 +99,22 @@ MachineInstrBuilder MachineIRBuilder::bu
.addUse(Op1);
}
+MachineInstrBuilder MachineIRBuilder::buildSub(LLT Ty, unsigned Res,
+ unsigned Op0, unsigned Op1) {
+ return buildInstr(TargetOpcode::G_SUB, Ty)
+ .addDef(Res)
+ .addUse(Op0)
+ .addUse(Op1);
+}
+
+MachineInstrBuilder MachineIRBuilder::buildMul(LLT Ty, unsigned Res,
+ unsigned Op0, unsigned Op1) {
+ return buildInstr(TargetOpcode::G_MUL, Ty)
+ .addDef(Res)
+ .addUse(Op0)
+ .addUse(Op1);
+}
+
MachineInstrBuilder MachineIRBuilder::buildBr(MachineBasicBlock &Dest) {
return buildInstr(TargetOpcode::G_BR, LLT::unsized()).addMBB(&Dest);
}
Modified: llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp?rev=279842&r1=279841&r2=279842&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp Fri Aug 26 12:46:13 2016
@@ -42,6 +42,8 @@ MachineLegalizeHelper::legalizeInstrStep
return narrowScalar(MI, std::get<1>(Action), std::get<2>(Action));
case MachineLegalizer::WidenScalar:
return widenScalar(MI, std::get<1>(Action), std::get<2>(Action));
+ case MachineLegalizer::Lower:
+ return lower(MI, std::get<1>(Action), std::get<2>(Action));
case MachineLegalizer::FewerElements:
return fewerElementsVector(MI, std::get<1>(Action), std::get<2>(Action));
default:
@@ -267,6 +269,33 @@ MachineLegalizeHelper::widenScalar(Machi
}
}
}
+
+MachineLegalizeHelper::LegalizeResult
+MachineLegalizeHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty) {
+ using namespace TargetOpcode;
+ unsigned Size = Ty.getSizeInBits();
+ MIRBuilder.setInstr(MI);
+
+ switch(MI.getOpcode()) {
+ default:
+ return UnableToLegalize;
+ case TargetOpcode::G_SREM:
+ case TargetOpcode::G_UREM: {
+ unsigned QuotReg = MRI.createGenericVirtualRegister(Size);
+ MIRBuilder.buildInstr(MI.getOpcode() == G_SREM ? G_SDIV : G_UDIV, Ty)
+ .addDef(QuotReg)
+ .addUse(MI.getOperand(1).getReg())
+ .addUse(MI.getOperand(2).getReg());
+
+ unsigned ProdReg = MRI.createGenericVirtualRegister(Size);
+ MIRBuilder.buildMul(Ty, ProdReg, QuotReg, MI.getOperand(2).getReg());
+ MIRBuilder.buildSub(Ty, MI.getOperand(0).getReg(),
+ MI.getOperand(1).getReg(), ProdReg);
+ MI.eraseFromParent();
+ return Legalized;
+ }
+ }
+}
MachineLegalizeHelper::LegalizeResult
MachineLegalizeHelper::fewerElementsVector(MachineInstr &MI, unsigned TypeIdx,
Modified: llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizer.cpp?rev=279842&r1=279841&r2=279842&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizer.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizer.cpp Fri Aug 26 12:46:13 2016
@@ -126,6 +126,7 @@ LLT MachineLegalizer::findLegalType(cons
default:
llvm_unreachable("Cannot find legal type");
case Legal:
+ case Lower:
return Aspect.Type;
case NarrowScalar: {
return findLegalType(Aspect,
Modified: llvm/trunk/lib/Target/AArch64/AArch64MachineLegalizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64MachineLegalizer.cpp?rev=279842&r1=279841&r2=279842&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64MachineLegalizer.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64MachineLegalizer.cpp Fri Aug 26 12:46:13 2016
@@ -51,6 +51,10 @@ AArch64MachineLegalizer::AArch64MachineL
setAction({BinOp, Ty}, WidenScalar);
}
+ for (auto BinOp : { G_SREM, G_UREM })
+ for (auto Ty : { s1, s8, s16, s32, s64 })
+ setAction({BinOp, Ty}, Lower);
+
for (auto Op : { G_UADDE, G_USUBE, G_SADDO, G_SSUBO, G_SMULO, G_UMULO }) {
for (auto Ty : { s32, s64 })
setAction({Op, Ty}, Legal);
Added: llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-rem.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-rem.mir?rev=279842&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-rem.mir (added)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-rem.mir Fri Aug 26 12:46:13 2016
@@ -0,0 +1,52 @@
+# 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_rem() {
+ entry:
+ ret void
+ }
+...
+
+---
+name: test_rem
+registers:
+ - { id: 0, class: _ }
+ - { id: 1, class: _ }
+ - { id: 2, class: _ }
+ - { id: 3, class: _ }
+ - { id: 4, class: _ }
+ - { id: 5, class: _ }
+ - { id: 6, class: _ }
+ - { id: 7, class: _ }
+ - { id: 8, class: _ }
+body: |
+ bb.0.entry:
+ liveins: %x0, %x1, %x2, %x3
+
+ ; CHECK: [[QUOT:%[0-9]+]](64) = G_UDIV s64 %0, %1
+ ; CHECK: [[PROD:%[0-9]+]](64) = G_MUL s64 [[QUOT]], %1
+ ; CHECK: [[RES:%[0-9]+]](64) = G_SUB s64 %0, [[PROD]]
+ %0(64) = COPY %x0
+ %1(64) = COPY %x1
+ %2(64) = G_UREM s64 %0, %1
+
+ ; CHECK: [[QUOT:%[0-9]+]](32) = G_SDIV s32 %3, %4
+ ; CHECK: [[PROD:%[0-9]+]](32) = G_MUL s32 [[QUOT]], %4
+ ; CHECK: [[RES:%[0-9]+]](32) = G_SUB s32 %3, [[PROD]]
+ %3(32) = G_TRUNC { s32, s64 } %0
+ %4(32) = G_TRUNC { s32, s64 } %1
+ %5(32) = G_SREM s32 %3, %4
+
+ ; CHECK: [[LHS32:%[0-9]+]](32) = G_SEXT { s32, s8 } %6
+ ; CHECK: [[RHS32:%[0-9]+]](32) = G_SEXT { s32, s8 } %7
+ ; CHECK: [[QUOT32:%[0-9]+]](32) = G_SDIV s32 [[LHS32]], [[RHS32]]
+ ; CHECK: [[QUOT:%[0-9]+]](8) = G_TRUNC { s8, s32 } [[QUOT32]]
+ ; CHECK: [[PROD:%[0-9]+]](8) = G_MUL s8 [[QUOT]], %7
+ ; CHECK: [[RES:%[0-9]+]](8) = G_SUB s8 %6, [[PROD]]
+ %6(8) = G_TRUNC { s8, s64 } %0
+ %7(8) = G_TRUNC { s8, s64 } %1
+ %8(8) = G_SREM s8 %6, %7
+
+...
Modified: llvm/trunk/unittests/CodeGen/GlobalISel/MachineLegalizerTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/CodeGen/GlobalISel/MachineLegalizerTest.cpp?rev=279842&r1=279841&r2=279842&view=diff
==============================================================================
--- llvm/trunk/unittests/CodeGen/GlobalISel/MachineLegalizerTest.cpp (original)
+++ llvm/trunk/unittests/CodeGen/GlobalISel/MachineLegalizerTest.cpp Fri Aug 26 12:46:13 2016
@@ -13,6 +13,7 @@
using namespace llvm;
using llvm::MachineLegalizer::LegalizeAction::Legal;
+using llvm::MachineLegalizer::LegalizeAction::Lower;
using llvm::MachineLegalizer::LegalizeAction::NarrowScalar;
using llvm::MachineLegalizer::LegalizeAction::WidenScalar;
using llvm::MachineLegalizer::LegalizeAction::FewerElements;
@@ -26,6 +27,7 @@ namespace llvm {
std::ostream &
operator<<(std::ostream &OS, const llvm::MachineLegalizer::LegalizeAction Act) {
switch (Act) {
+ case Lower: OS << "Lower"; break;
case Legal: OS << "Legal"; break;
case NarrowScalar: OS << "NarrowScalar"; break;
case WidenScalar: OS << "WidenScalar"; break;
More information about the llvm-commits
mailing list