forked from OSchip/llvm-project
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 llvm-svn: 133034
This commit is contained in:
parent
70f05fdfee
commit
6d02d9044b
|
@ -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));
|
||||
|
|
|
@ -61,3 +61,16 @@ entry:
|
|||
%3 = or i32 %2, %0
|
||||
ret i32 %3
|
||||
}
|
||||
|
||||
; rdar://9609030
|
||||
define i32 @f6(i32 %a, i32 %b) nounwind readnone {
|
||||
entry:
|
||||
; CHECK: f6:
|
||||
; CHECK-NOT: bic
|
||||
; CHECK: bfi r0, r1, #8, #9
|
||||
%and = and i32 %a, -130817
|
||||
%and2 = shl i32 %b, 8
|
||||
%shl = and i32 %and2, 130816
|
||||
%or = or i32 %shl, %and
|
||||
ret i32 %or
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue