[llvm] r277747 - GlobalISel: add code to widen scalar G_ADD

Tim Northover via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 4 11:35:11 PDT 2016


Author: tnorthover
Date: Thu Aug  4 13:35:11 2016
New Revision: 277747

URL: http://llvm.org/viewvc/llvm-project?rev=277747&view=rev
Log:
GlobalISel: add code to widen scalar G_ADD

Modified:
    llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
    llvm/trunk/include/llvm/Target/GenericOpcodes.td
    llvm/trunk/include/llvm/Target/TargetOpcodes.def
    llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
    llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
    llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizer.cpp
    llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-add.mir

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=277747&r1=277746&r2=277747&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h Thu Aug  4 13:35:11 2016
@@ -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.

Modified: llvm/trunk/include/llvm/Target/GenericOpcodes.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/GenericOpcodes.td?rev=277747&r1=277746&r2=277747&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/GenericOpcodes.td (original)
+++ llvm/trunk/include/llvm/Target/GenericOpcodes.td Thu Aug  4 13:35:11 2016
@@ -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.
 //------------------------------------------------------------------------------

Modified: llvm/trunk/include/llvm/Target/TargetOpcodes.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetOpcodes.def?rev=277747&r1=277746&r2=277747&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetOpcodes.def (original)
+++ llvm/trunk/include/llvm/Target/TargetOpcodes.def Thu Aug  4 13:35:11 2016
@@ -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)
 

Modified: llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp?rev=277747&r1=277746&r2=277747&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp Thu Aug  4 13:35:11 2016
@@ -119,6 +119,11 @@ MachineInstrBuilder MachineIRBuilder::bu
       .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::bu
   MIB.addIntrinsicID(ID);
   return MIB;
 }
+
+MachineInstrBuilder MachineIRBuilder::buildTrunc(LLT Ty, unsigned Res,
+                                           unsigned Op) {
+  return buildInstr(TargetOpcode::G_TRUNC, Ty).addDef(Res).addUse(Op);
+}

Modified: llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp?rev=277747&r1=277746&r2=277747&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp Thu Aug  4 13:35:11 2016
@@ -66,7 +66,30 @@ MachineLegalizeHelper::narrowScalar(Mach
 
 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

Modified: llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizer.cpp?rev=277747&r1=277746&r2=277747&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizer.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizer.cpp Thu Aug  4 13:35:11 2016
@@ -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;
 }
 

Modified: llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-add.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-add.mir?rev=277747&r1=277746&r2=277747&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-add.mir (original)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-add.mir Thu Aug  4 13:35:11 2016
@@ -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:




More information about the llvm-commits mailing list