[llvm-commits] [llvm] r103881 - in /llvm/trunk: lib/Target/ARM/ARMISelLowering.cpp test/CodeGen/ARM/mul_const.ll

Evan Cheng evan.cheng at apple.com
Sat May 15 16:37:36 PDT 2010


Hi Anton, 

Please move it to general dag combiner for all power of two cases. Special casing for 3, 5, 7, 9 is fairly ugly. Jakob, I think you have a dag combine patch for this? It wasn't profitable for x86, but perhaps it's good for other targets.

Evan

On May 15, 2010, at 11:16 AM, Anton Korobeynikov wrote:

> Author: asl
> Date: Sat May 15 13:16:59 2010
> New Revision: 103881
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=103881&view=rev
> Log:
> Some cheap DAG combine goodness for multiplication with a particular constant.
> This can be extended later on to handle more "complex" constants.
> 
> Modified:
>    llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
>    llvm/trunk/test/CodeGen/ARM/mul_const.ll
> 
> Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=103881&r1=103880&r2=103881&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Sat May 15 13:16:59 2010
> @@ -463,6 +463,7 @@
>   // ARMISD::VMOVRRD  - No need to call setTargetDAGCombine
>   setTargetDAGCombine(ISD::ADD);
>   setTargetDAGCombine(ISD::SUB);
> +  setTargetDAGCombine(ISD::MUL);
> 
>   setStackPointerRegisterToSaveRestore(ARM::SP);
>   setSchedulingPreference(SchedulingForRegPressure);
> @@ -3584,6 +3585,75 @@
>   return SDValue();
> }
> 
> +static SDValue PerformMULCombine(SDNode *N,
> +                                 TargetLowering::DAGCombinerInfo &DCI,
> +                                 const ARMSubtarget *Subtarget) {
> +  SelectionDAG &DAG = DCI.DAG;
> +
> +  if (Subtarget->isThumb1Only())
> +    return SDValue();
> +
> +  if (DAG.getMachineFunction().
> +      getFunction()->hasFnAttr(Attribute::OptimizeForSize))
> +    return SDValue();
> +
> +  if (DCI.isBeforeLegalize() || DCI.isCalledByLegalizer())
> +    return SDValue();
> +
> +  EVT VT = N->getValueType(0);
> +  if (VT != MVT::i32)
> +    return SDValue();
> +
> +  ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1));
> +  if (!C)
> +    return SDValue();
> +
> +  uint64_t MulAmt = C->getZExtValue();
> +  unsigned ShiftAmt = CountTrailingZeros_64(MulAmt);
> +  ShiftAmt = ShiftAmt & (32 - 1);
> +  SDValue V = N->getOperand(0);
> +  DebugLoc DL = N->getDebugLoc();
> +  SDValue NewAdd;
> +
> +  // FIXME: Handle arbitrary powers of 2.
> +  switch (MulAmt >> ShiftAmt) {
> +  case 3: // 2 + 1
> +    NewAdd = DAG.getNode(ISD::ADD, DL, VT,
> +                         V, DAG.getNode(ISD::SHL, DL, VT,
> +                                        V, DAG.getConstant(1, MVT::i32)));
> +   break;
> +  case 5: // 4 + 1
> +    NewAdd = DAG.getNode(ISD::ADD, DL, VT,
> +                         V, DAG.getNode(ISD::SHL, DL, VT,
> +                                        V, DAG.getConstant(2, MVT::i32)));
> +    break;
> +  case 7: // 8 - 1
> +    NewAdd = DAG.getNode(ISD::SUB, DL, VT,
> +                         DAG.getNode(ISD::SHL, DL, VT,
> +                                     V, DAG.getConstant(3, MVT::i32)),
> +                         V);
> +    break;
> +  case 9: // 8 + 1
> +    NewAdd = DAG.getNode(ISD::ADD, DL, VT,
> +                         V, DAG.getNode(ISD::SHL, DL, VT,
> +                                        V, DAG.getConstant(3, MVT::i32)));
> +    break;
> +  default: return SDValue();
> +  }
> +
> +  if (ShiftAmt != 0) {
> +    SDValue NewShift = DAG.getNode(ISD::SHL, DL, VT, NewAdd,
> +                                   DAG.getConstant(ShiftAmt, MVT::i32));
> +    // Do not add new nodes to DAG combiner worklist.
> +    DCI.CombineTo(N, NewShift, false);
> +    return SDValue();
> +  }
> +
> +  // Do not add new nodes to DAG combiner worklist.
> +  DCI.CombineTo(N, NewAdd, false);
> +  return SDValue();
> +}
> +
> /// PerformVMOVRRDCombine - Target-specific dag combine xforms for
> /// ARMISD::VMOVRRD.
> static SDValue PerformVMOVRRDCombine(SDNode *N,
> @@ -3970,6 +4040,7 @@
>   default: break;
>   case ISD::ADD:        return PerformADDCombine(N, DCI);
>   case ISD::SUB:        return PerformSUBCombine(N, DCI);
> +  case ISD::MUL:        return PerformMULCombine(N, DCI, Subtarget);
>   case ARMISD::VMOVRRD: return PerformVMOVRRDCombine(N, DCI);
>   case ISD::INTRINSIC_WO_CHAIN: return PerformIntrinsicCombine(N, DCI.DAG);
>   case ISD::SHL:
> 
> Modified: llvm/trunk/test/CodeGen/ARM/mul_const.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/mul_const.ll?rev=103881&r1=103880&r2=103881&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/ARM/mul_const.ll (original)
> +++ llvm/trunk/test/CodeGen/ARM/mul_const.ll Sat May 15 13:16:59 2010
> @@ -1,17 +1,43 @@
> ; RUN: llc < %s -march=arm | FileCheck %s
> 
> -define i32 @t1(i32 %v) nounwind readnone {
> +define i32 @t9(i32 %v) nounwind readnone {
> entry:
> -; CHECK: t1:
> +; CHECK: t9:
> ; CHECK: add r0, r0, r0, lsl #3
> 	%0 = mul i32 %v, 9
> 	ret i32 %0
> }
> 
> -define i32 @t2(i32 %v) nounwind readnone {
> +define i32 @t7(i32 %v) nounwind readnone {
> entry:
> -; CHECK: t2:
> +; CHECK: t7:
> ; CHECK: rsb r0, r0, r0, lsl #3
> 	%0 = mul i32 %v, 7
> 	ret i32 %0
> }
> +
> +define i32 @t5(i32 %v) nounwind readnone {
> +entry:
> +; CHECK: t5:
> +; CHECK: add r0, r0, r0, lsl #2
> +        %0 = mul i32 %v, 5
> +        ret i32 %0
> +}
> +
> +define i32 @t3(i32 %v) nounwind readnone {
> +entry:
> +; CHECK: t3:
> +; CHECK: add r0, r0, r0, lsl #1
> +        %0 = mul i32 %v, 3
> +        ret i32 %0
> +}
> +
> +define i32 @t12288(i32 %v) nounwind readnone {
> +entry:
> +; CHECK: t12288:
> +; CHECK: add r0, r0, r0, lsl #1
> +; CHECK: mov     r0, r0, lsl #12
> +        %0 = mul i32 %v, 12288
> +        ret i32 %0
> +}
> +
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits





More information about the llvm-commits mailing list