Mesa (master): radeon/llvm: Lower ROTL to BIT_ALIGN

Tom Stellard tstellar at kemper.freedesktop.org
Thu Jun 21 20:50:12 UTC 2012


Module: Mesa
Branch: master
Commit: c53c8d05551083437eb991e79002c0a272541a79
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=c53c8d05551083437eb991e79002c0a272541a79

Author: Tom Stellard <thomas.stellard at amd.com>
Date:   Wed Jun 20 16:28:01 2012 -0400

radeon/llvm: Lower ROTL to BIT_ALIGN

---

 src/gallium/drivers/radeon/AMDGPUISelLowering.h  |    1 +
 src/gallium/drivers/radeon/AMDGPUInstrInfo.td    |   14 +++++++++++
 src/gallium/drivers/radeon/AMDILISelLowering.cpp |    1 -
 src/gallium/drivers/radeon/R600ISelLowering.cpp  |   28 ++++++++++++++++++++++
 src/gallium/drivers/radeon/R600ISelLowering.h    |    4 +++
 src/gallium/drivers/radeon/R600Instructions.td   |    7 +++++
 6 files changed, 54 insertions(+), 1 deletions(-)

diff --git a/src/gallium/drivers/radeon/AMDGPUISelLowering.h b/src/gallium/drivers/radeon/AMDGPUISelLowering.h
index 9aa602b..72342c9 100644
--- a/src/gallium/drivers/radeon/AMDGPUISelLowering.h
+++ b/src/gallium/drivers/radeon/AMDGPUISelLowering.h
@@ -57,6 +57,7 @@ namespace AMDGPUISD
 enum
 {
   AMDGPU_FIRST = AMDILISD::LAST_ISD_NUMBER,
+  BITALIGN,
   FRACT,
   FMAX,
   SMAX,
diff --git a/src/gallium/drivers/radeon/AMDGPUInstrInfo.td b/src/gallium/drivers/radeon/AMDGPUInstrInfo.td
index 5e44ef9..4452719 100644
--- a/src/gallium/drivers/radeon/AMDGPUInstrInfo.td
+++ b/src/gallium/drivers/radeon/AMDGPUInstrInfo.td
@@ -12,9 +12,23 @@
 //===----------------------------------------------------------------------===//
 
 //===----------------------------------------------------------------------===//
+// AMDGPU DAG Profiles
+//===----------------------------------------------------------------------===//
+
+def AMDGPUDTIntTernaryOp : SDTypeProfile<1, 3, [
+  SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<0>, SDTCisInt<3>
+]>;
+
+//===----------------------------------------------------------------------===//
 // AMDGPU DAG Nodes
 //
 
+// out = ((a << 32) | b) >> c)
+//
+// Can be used to optimize rtol:
+// rotl(a, b) = bitalign(a, a, 32 - b)
+def AMDGPUbitalign : SDNode<"AMDGPUISD::BITALIGN", AMDGPUDTIntTernaryOp>;
+
 // out = a - floor(a)
 def AMDGPUfract : SDNode<"AMDGPUISD::FRACT", SDTFPUnaryOp>;
 
diff --git a/src/gallium/drivers/radeon/AMDILISelLowering.cpp b/src/gallium/drivers/radeon/AMDILISelLowering.cpp
index 12b3dce..2838001 100644
--- a/src/gallium/drivers/radeon/AMDILISelLowering.cpp
+++ b/src/gallium/drivers/radeon/AMDILISelLowering.cpp
@@ -564,7 +564,6 @@ AMDILTargetLowering::LowerMemArgument(
 
     // GPU doesn't have a rotl, rotr, or byteswap instruction
     setOperationAction(ISD::ROTR, VT, Expand);
-    setOperationAction(ISD::ROTL, VT, Expand);
     setOperationAction(ISD::BSWAP, VT, Expand);
 
     // GPU doesn't have any counting operators
diff --git a/src/gallium/drivers/radeon/R600ISelLowering.cpp b/src/gallium/drivers/radeon/R600ISelLowering.cpp
index 3e021a2..5694c0b 100644
--- a/src/gallium/drivers/radeon/R600ISelLowering.cpp
+++ b/src/gallium/drivers/radeon/R600ISelLowering.cpp
@@ -33,6 +33,8 @@ R600TargetLowering::R600TargetLowering(TargetMachine &TM) :
 
   setOperationAction(ISD::FSUB, MVT::f32, Expand);
 
+  setOperationAction(ISD::ROTL, MVT::i32, Custom);
+
   setSchedulingPreference(Sched::VLIW);
 }
 
@@ -256,3 +258,29 @@ void R600TargetLowering::lowerImplicitParameter(MachineInstr *MI, MachineBasicBl
           .addReg(PtrReg)
           .addImm(0);
 }
+
+//===----------------------------------------------------------------------===//
+// Custom DAG Lowering Operations
+//===----------------------------------------------------------------------===//
+
+
+SDValue R600TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const
+{
+  switch (Op.getOpcode()) {
+  default: return AMDGPUTargetLowering::LowerOperation(Op, DAG);
+  case ISD::ROTL: return LowerROTL(Op, DAG);
+  }
+}
+
+SDValue R600TargetLowering::LowerROTL(SDValue Op, SelectionDAG &DAG) const
+{
+  DebugLoc DL = Op.getDebugLoc();
+  EVT VT = Op.getValueType();
+
+  return DAG.getNode(AMDGPUISD::BITALIGN, DL, VT,
+                     Op.getOperand(0),
+                     Op.getOperand(0),
+                     DAG.getNode(ISD::SUB, DL, VT,
+                                 DAG.getConstant(32, MVT::i32),
+                                 Op.getOperand(1)));
+}
diff --git a/src/gallium/drivers/radeon/R600ISelLowering.h b/src/gallium/drivers/radeon/R600ISelLowering.h
index 6296145..7b91373 100644
--- a/src/gallium/drivers/radeon/R600ISelLowering.h
+++ b/src/gallium/drivers/radeon/R600ISelLowering.h
@@ -26,6 +26,7 @@ public:
   R600TargetLowering(TargetMachine &TM);
   virtual MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr *MI,
       MachineBasicBlock * BB) const;
+  virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const;
 
 private:
   const R600InstrInfo * TII;
@@ -37,6 +38,9 @@ private:
   void lowerImplicitParameter(MachineInstr *MI, MachineBasicBlock &BB,
       MachineRegisterInfo & MRI, unsigned dword_offset) const;
 
+  /// LowerROTL - Lower ROTL opcode to BITALIGN
+  SDValue LowerROTL(SDValue Op, SelectionDAG &DAG) const;
+
 };
 
 } // End namespace llvm;
diff --git a/src/gallium/drivers/radeon/R600Instructions.td b/src/gallium/drivers/radeon/R600Instructions.td
index 4be9fca..409969b 100644
--- a/src/gallium/drivers/radeon/R600Instructions.td
+++ b/src/gallium/drivers/radeon/R600Instructions.td
@@ -821,6 +821,13 @@ def RECIP_UINT_eg : RECIP_UINT_Common<0x94>;
 /* ------------------------------- */
 
 let Predicates = [isEGorCayman] in {
+
+  def BIT_ALIGN_INT_eg : R600_3OP <0xC, "BIT_ALIGN_INT",
+    [(set R600_Reg32:$dst, (AMDGPUbitalign R600_Reg32:$src0, R600_Reg32:$src1,
+                                          R600_Reg32:$src2))],
+    VecALU
+  >;
+
   def MULADD_eg : MULADD_Common<0x14>;
   def ASHR_eg : ASHR_Common<0x15>;
   def LSHR_eg : LSHR_Common<0x16>;




More information about the mesa-commit mailing list