radeon/llvm: Move lowering of ABS_i32 to ISel
authorTom Stellard <thomas.stellard@amd.com>
Thu, 17 May 2012 16:08:21 +0000 (12:08 -0400)
committerTom Stellard <thomas.stellard@amd.com>
Thu, 17 May 2012 18:48:09 +0000 (14:48 -0400)
src/gallium/drivers/radeon/AMDGPUISelLowering.cpp
src/gallium/drivers/radeon/AMDGPUISelLowering.h
src/gallium/drivers/radeon/AMDILInstructions.td
src/gallium/drivers/radeon/R600LowerInstructions.cpp

index 9d1042e..921daa6 100644 (file)
@@ -43,6 +43,8 @@ SDValue AMDGPUTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
 
   switch (IntrinsicID) {
     default: return Op;
+    case AMDGPUIntrinsic::AMDIL_abs:
+      return LowerIntrinsicIABS(Op, DAG);
     case AMDGPUIntrinsic::AMDIL_max:
       return DAG.getNode(AMDGPUISD::FMAX, DL, VT, Op.getOperand(1),
                                                   Op.getOperand(2));
@@ -55,6 +57,19 @@ SDValue AMDGPUTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
   }
 }
 
+///IABS(a) = SMAX(sub(0, a), a)
+SDValue AMDGPUTargetLowering::LowerIntrinsicIABS(SDValue Op,
+    SelectionDAG &DAG) const
+{
+
+  DebugLoc DL = Op.getDebugLoc();
+  EVT VT = Op.getValueType();
+  SDValue Neg = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, VT),
+                                              Op.getOperand(1));
+
+  return DAG.getNode(AMDGPUISD::SMAX, DL, VT, Neg, Op.getOperand(1));
+}
+
 void AMDGPUTargetLowering::addLiveIn(MachineInstr * MI,
     MachineFunction * MF, MachineRegisterInfo & MRI,
     const TargetInstrInfo * TII, unsigned reg) const
index b67f30b..e4c7787 100644 (file)
@@ -40,6 +40,7 @@ public:
   AMDGPUTargetLowering(TargetMachine &TM);
 
   virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const;
+  SDValue LowerIntrinsicIABS(SDValue Op, SelectionDAG &DAG) const;
   virtual const char* getTargetNodeName(unsigned Opcode) const;
 
 };
index f03ec6b..3ee7836 100644 (file)
@@ -92,7 +92,6 @@ def ADDri       : TwoInOneOut<IL_OP_I_ADD, (outs GPRI32:$dst),
 defm IFFB_HI    : UnaryOpMCi32<IL_OP_I_FFB_HI, IL_ffb_hi>;
 defm IFFB_LO    : UnaryOpMCi32<IL_OP_I_FFB_LO, IL_ffb_lo>;
 let mayLoad = 0, mayStore = 0 in {
-defm ABS : UnaryIntrinsicInt<IL_OP_ABS, int_AMDIL_abs>;
 defm BITCOUNT : UnaryIntrinsicInt<IL_OP_IBIT_COUNT, int_AMDIL_bit_count_i32>;
 defm FFB_LO : UnaryIntrinsicInt<IL_OP_I_FFB_LO, int_AMDIL_bit_find_first_lo>;
 defm FFB_HI : UnaryIntrinsicInt<IL_OP_I_FFB_HI, int_AMDIL_bit_find_first_hi>;
index 42c9766..2edae32 100644 (file)
@@ -88,22 +88,6 @@ bool R600LowerInstructionsPass::runOnMachineFunction(MachineFunction &MF)
                 .addOperand(MI.getOperand(1));
         break;
 
-      case AMDIL::ABS_i32:
-        {
-          unsigned neg = MRI->createVirtualRegister(
-                           &AMDIL::R600_TReg32RegClass);
-          BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(AMDIL::SUB_INT),neg)
-                  .addReg(AMDIL::ZERO)
-                  .addOperand(MI.getOperand(1));
-
-          BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(AMDIL::MAX_INT))
-                  .addOperand(MI.getOperand(0))
-                  .addOperand(MI.getOperand(1))
-                  .addReg(neg);
-
-          break;
-        }
-
       /* XXX: We could propagate the ABS flag to all of the uses of Operand0 and
        * remove the ABS instruction.*/
       case AMDIL::FABS_f32: