diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h | 22 | ||||
-rw-r--r-- | llvm/include/llvm/Target/GenericOpcodes.td | 19 | ||||
-rw-r--r-- | llvm/include/llvm/Target/TargetOpcodes.def | 6 | ||||
-rw-r--r-- | llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp | 10 | ||||
-rw-r--r-- | llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp | 25 | ||||
-rw-r--r-- | llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp | 5 | ||||
-rw-r--r-- | llvm/test/CodeGen/AArch64/GlobalISel/legalize-add.mir | 26 |
7 files changed, 112 insertions, 1 deletions
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h index e83ade6e886..11785031a4a 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h @@ -131,6 +131,18 @@ public: MachineInstrBuilder buildAdd(LLT Ty, unsigned Res, unsigned Op0, unsigned Op1); + /// Build and insert \p Res<def> = G_ANYEXTEND \p Ty \p Op0 + /// + /// G_ANYEXTEND produces a register of the specified width, with bits 0 to + /// sizeof(\p Ty) * 8 set to \p Op. The remaining bits are unspecified + /// (i.e. this is neither zero nor sign-extension). For a vector register, + /// each element is extended individually. + /// + /// \pre setBasicBlock or setMI must have been called. + /// + /// \return The newly created instruction. + MachineInstrBuilder buildAnyExtend(LLT Ty, unsigned Res, unsigned Op); + /// Build and insert G_BR unsized \p Dest /// /// G_BR is an unconditional branch to \p Dest. @@ -217,6 +229,16 @@ public: /// \return a MachineInstrBuilder for the newly created instruction. MachineInstrBuilder buildIntrinsic(ArrayRef<LLT> Tys, Intrinsic::ID ID, unsigned Res, bool HasSideEffects); + + /// Build and insert \p Res<def> = G_TRUNC \p Ty \p Op + /// + /// G_TRUNC extracts the low bits of a type. For a vector type each element is + /// truncated independently before being packed into the destination. + /// + /// \pre setBasicBlock or setMI must have been called. + /// + /// \return The newly created instruction. + MachineInstrBuilder buildTrunc(LLT Ty, unsigned Res, unsigned Op); }; } // End namespace llvm. diff --git a/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td index 7dd0c070fa2..aa7639cae90 100644 --- a/llvm/include/llvm/Target/GenericOpcodes.td +++ b/llvm/include/llvm/Target/GenericOpcodes.td @@ -12,6 +12,25 @@ // //===----------------------------------------------------------------------===// +// Unary ops. +//------------------------------------------------------------------------------ + +// Extend the underlying scalar type of an operation, leaving the high bits +// unspecified. +def G_ANYEXTEND : Instruction { + let OutOperandList = (outs unknown:$dst); + let InOperandList = (ins unknown:$src); + let hasSideEffects = 0; +} + +// Truncate the underlying scalar type of an operation. This is equivalent to +// G_EXTRACT for scalar types, but acts elementwise on vectors. +def G_TRUNC : Instruction { + let OutOperandList = (outs unknown:$dst); + let InOperandList = (ins unknown:$src); + let hasSideEffects = 0; +} + //------------------------------------------------------------------------------ // Unary ops. //------------------------------------------------------------------------------ diff --git a/llvm/include/llvm/Target/TargetOpcodes.def b/llvm/include/llvm/Target/TargetOpcodes.def index 7c8a1df7299..01a589b8a59 100644 --- a/llvm/include/llvm/Target/TargetOpcodes.def +++ b/llvm/include/llvm/Target/TargetOpcodes.def @@ -208,6 +208,12 @@ HANDLE_TARGET_OPCODE(G_INTRINSIC) /// Generic intrinsic use (with side effects). HANDLE_TARGET_OPCODE(G_INTRINSIC_W_SIDE_EFFECTS) +/// Generic extension allowing rubbish in high bits. +HANDLE_TARGET_OPCODE(G_ANYEXTEND) + +/// Generic truncation. +HANDLE_TARGET_OPCODE(G_TRUNC) + /// Generic BRANCH instruction. This is an unconditional branch. HANDLE_TARGET_OPCODE(G_BR) diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp index 5e737d5e2bb..09a8fa6001b 100644 --- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp +++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp @@ -119,6 +119,11 @@ MachineInstrBuilder MachineIRBuilder::buildStore(LLT VTy, LLT PTy, .addMemOperand(&MMO); } +MachineInstrBuilder MachineIRBuilder::buildAnyExtend(LLT Ty, unsigned Res, + unsigned Op) { + return buildInstr(TargetOpcode::G_ANYEXTEND, Ty).addDef(Res).addUse(Op); +} + MachineInstrBuilder MachineIRBuilder::buildExtract(LLT Ty, ArrayRef<unsigned> Results, unsigned Src, ArrayRef<unsigned> Indexes) { @@ -157,3 +162,8 @@ MachineInstrBuilder MachineIRBuilder::buildIntrinsic(ArrayRef<LLT> Tys, MIB.addIntrinsicID(ID); return MIB; } + +MachineInstrBuilder MachineIRBuilder::buildTrunc(LLT Ty, unsigned Res, + unsigned Op) { + return buildInstr(TargetOpcode::G_TRUNC, Ty).addDef(Res).addUse(Op); +} diff --git a/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp b/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp index 55adbbd20ce..71d3206dc55 100644 --- a/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp @@ -66,7 +66,30 @@ MachineLegalizeHelper::narrowScalar(MachineInstr &MI, LLT NarrowTy) { MachineLegalizeHelper::LegalizeResult MachineLegalizeHelper::widenScalar(MachineInstr &MI, LLT WideTy) { - return UnableToLegalize; + switch (MI.getOpcode()) { + default: + return UnableToLegalize; + case TargetOpcode::G_ADD: { + // Perform operation at larger width (any extension is fine here, high bits + // don't affect the result) and then truncate the result back to the + // original type. + unsigned WideSize = WideTy.getSizeInBits(); + + MIRBuilder.setInstr(MI); + + unsigned Src1Ext = MRI.createGenericVirtualRegister(WideSize); + unsigned Src2Ext = MRI.createGenericVirtualRegister(WideSize); + MIRBuilder.buildAnyExtend(WideTy, Src1Ext, MI.getOperand(1).getReg()); + MIRBuilder.buildAnyExtend(WideTy, Src2Ext, MI.getOperand(2).getReg()); + + unsigned DstExt = MRI.createGenericVirtualRegister(WideSize); + MIRBuilder.buildAdd(WideTy, DstExt, Src1Ext, Src2Ext); + + MIRBuilder.buildTrunc(MI.getType(), MI.getOperand(0).getReg(), DstExt); + MI.eraseFromParent(); + return Legalized; + } + } } MachineLegalizeHelper::LegalizeResult diff --git a/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp b/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp index 6856ed57a0b..881b5026fa6 100644 --- a/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp +++ b/llvm/lib/CodeGen/GlobalISel/MachineLegalizer.cpp @@ -25,6 +25,11 @@ using namespace llvm; MachineLegalizer::MachineLegalizer() : TablesInitialized(false) { + // FIXME: these two can be legalized to the fundamental load/store Jakob + // proposed. Once loads & stores are supported. + DefaultActions[TargetOpcode::G_ANYEXTEND] = Legal; + DefaultActions[TargetOpcode::G_TRUNC] = Legal; + DefaultActions[TargetOpcode::G_ADD] = NarrowScalar; } diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-add.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-add.mir index b47d8752f8d..9078db5a518 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-add.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-add.mir @@ -3,6 +3,10 @@ --- | target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" target triple = "aarch64-apple-ios" + define void @test_scalar_add_small() { + entry: + ret void + } define void @test_vector_add() { entry: ret void @@ -10,6 +14,28 @@ ... --- +name: test_scalar_add_small +isSSA: true +registers: + - { id: 0, class: _ } + - { id: 1, class: _ } + - { id: 2, class: _ } +body: | + bb.0.entry: + liveins: %x0, %x1, %x2, %x3 + ; CHECK-LABEL: name: test_scalar_add_small + ; CHECK-DAG: [[LHS:%.*]](32) = G_ANYEXTEND s32 %0 + ; CHECK-DAG: [[RHS:%.*]](32) = G_ANYEXTEND s32 %1 + ; CHECK: [[RES:%.*]](32) = G_ADD s32 [[LHS]], [[RHS]] + ; CHECK: %2(8) = G_TRUNC s8 [[RES]] + + %0(8) = G_TRUNC s8 %x0 + %1(8) = G_TRUNC s8 %x1 + %2(8) = G_ADD s8 %0, %1 + %x0 = G_ANYEXTEND s64 %2 +... + +--- name: test_vector_add isSSA: true registers: |