From: Evan Cheng Date: Tue, 14 Dec 2010 03:22:07 +0000 (+0000) Subject: bfi A, (and B, C1), C2) -> bfi A, B, C2 iff C1 & C2 == C1. rdar://8458663 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=0c1aec18911f2a67fb37b6593d08f4f8cb7e18ef;p=oota-llvm.git bfi A, (and B, C1), C2) -> bfi A, B, C2 iff C1 & C2 == C1. rdar://8458663 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121746 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 3af04f104ba..5fbc5f8ce75 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -4809,6 +4809,25 @@ static SDValue PerformORCombine(SDNode *N, return SDValue(); } +/// PerformBFICombine - (bfi A, (and B, C1), C2) -> (bfi A, B, C2) iff +/// C1 & C2 == C1. +static SDValue PerformBFICombine(SDNode *N, + TargetLowering::DAGCombinerInfo &DCI) { + SDValue N1 = N->getOperand(1); + if (N1.getOpcode() == ISD::AND) { + ConstantSDNode *N11C = dyn_cast(N1.getOperand(1)); + if (!N11C) + return SDValue(); + unsigned Mask = cast(N->getOperand(2))->getZExtValue(); + unsigned Mask2 = N11C->getZExtValue(); + if ((Mask & Mask2) == Mask2) + return DCI.DAG.getNode(ARMISD::BFI, N->getDebugLoc(), N->getValueType(0), + N->getOperand(0), N1.getOperand(0), + N->getOperand(2)); + } + return SDValue(); +} + /// PerformVMOVRRDCombine - Target-specific dag combine xforms for /// ARMISD::VMOVRRD. static SDValue PerformVMOVRRDCombine(SDNode *N, @@ -5398,6 +5417,7 @@ SDValue ARMTargetLowering::PerformDAGCombine(SDNode *N, case ISD::MUL: return PerformMULCombine(N, DCI, Subtarget); case ISD::OR: return PerformORCombine(N, DCI, Subtarget); case ISD::AND: return PerformANDCombine(N, DCI); + case ARMISD::BFI: return PerformBFICombine(N, DCI); case ARMISD::VMOVRRD: return PerformVMOVRRDCombine(N, DCI); case ARMISD::VMOVDRR: return PerformVMOVDRRCombine(N, DCI.DAG); case ISD::BUILD_VECTOR: return PerformBUILD_VECTORCombine(N, DCI.DAG); diff --git a/test/CodeGen/ARM/bfi.ll b/test/CodeGen/ARM/bfi.ll index 157c90c7531..946db1909fe 100644 --- a/test/CodeGen/ARM/bfi.ll +++ b/test/CodeGen/ARM/bfi.ll @@ -49,3 +49,16 @@ define i32 @f4(i32 %a) nounwind { %ins12 = or i32 %ins7, 3137 ret i32 %ins12 } + +; rdar://8458663 +define i32 @f5(i32 %a, i32 %b) nounwind { +entry: +; CHECK: f5: +; CHECK-NOT: bfc +; CHECK: bfi r0, r1, #20, #4 + %0 = and i32 %a, -15728641 + %1 = shl i32 %b, 20 + %2 = and i32 %1, 15728640 + %3 = or i32 %2, %0 + ret i32 %3 +}