[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