summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2011-06-15 01:12:31 +0000
committerEvan Cheng <evan.cheng@apple.com>2011-06-15 01:12:31 +0000
commitbf188aeae7a579fb71480be7d32a2edc4d56d827 (patch)
treebb4fb35062d992f7249a8027f3cd0fa869615a60 /lib
parentcf886188fb04d9521db39fe5213df1295673f51e (diff)
downloadllvm-bf188aeae7a579fb71480be7d32a2edc4d56d827.tar.gz
llvm-bf188aeae7a579fb71480be7d32a2edc4d56d827.tar.bz2
llvm-bf188aeae7a579fb71480be7d32a2edc4d56d827.tar.xz
PerformBFICombine - (bfi A, (and B, Mask1), Mask2) -> (bfi A, B, Mask2) iff
the bits being cleared by the AND are not demanded by the BFI. The previous BFI dag combine rule was actually incorrect (or used to be correct until BFI representation changed). rdar://9609030 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@133034 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp11
1 files changed, 7 insertions, 4 deletions
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index c4513fd97d..358eb597cc 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -5976,8 +5976,8 @@ static SDValue PerformORCombine(SDNode *N,
return SDValue();
}
-/// PerformBFICombine - (bfi A, (and B, C1), C2) -> (bfi A, B, C2) iff
-/// C1 & C2 == C1.
+/// PerformBFICombine - (bfi A, (and B, Mask1), Mask2) -> (bfi A, B, Mask2) iff
+/// the bits being cleared by the AND are not demanded by the BFI.
static SDValue PerformBFICombine(SDNode *N,
TargetLowering::DAGCombinerInfo &DCI) {
SDValue N1 = N->getOperand(1);
@@ -5985,9 +5985,12 @@ static SDValue PerformBFICombine(SDNode *N,
ConstantSDNode *N11C = dyn_cast<ConstantSDNode>(N1.getOperand(1));
if (!N11C)
return SDValue();
- unsigned Mask = cast<ConstantSDNode>(N->getOperand(2))->getZExtValue();
+ unsigned InvMask = cast<ConstantSDNode>(N->getOperand(2))->getZExtValue();
+ unsigned LSB = CountTrailingZeros_32(~InvMask);
+ unsigned Width = (32 - CountLeadingZeros_32(~InvMask)) - LSB;
+ unsigned Mask = (1 << Width)-1;
unsigned Mask2 = N11C->getZExtValue();
- if ((Mask & Mask2) == Mask2)
+ if ((Mask & (~Mask2)) == 0)
return DCI.DAG.getNode(ARMISD::BFI, N->getDebugLoc(), N->getValueType(0),
N->getOperand(0), N1.getOperand(0),
N->getOperand(2));