mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
Fix the bfi handling for or (and a mask) (and b mask). We need the two
masks to match inversely for the code as is to work. For the example given we actually want: bfi r0, r2, #1, #1 not #0, however, given the way the pattern is written it's not possible at the moment. Fixes rdar://9177502 llvm-svn: 128320
This commit is contained in:
parent
72b390743d
commit
b51c27cd9a
@ -5168,6 +5168,7 @@ static SDValue PerformMULCombine(SDNode *N,
|
||||
|
||||
static SDValue PerformANDCombine(SDNode *N,
|
||||
TargetLowering::DAGCombinerInfo &DCI) {
|
||||
|
||||
// Attempt to use immediate-form VBIC
|
||||
BuildVectorSDNode *BVN = dyn_cast<BuildVectorSDNode>(N->getOperand(1));
|
||||
DebugLoc dl = N->getDebugLoc();
|
||||
@ -5241,9 +5242,9 @@ static SDValue PerformORCombine(SDNode *N,
|
||||
//
|
||||
// 2) or (and A, mask), (and B, mask2) => ARMbfi A, (lsr B, amt), mask
|
||||
// 2a) iff isBitFieldInvertedMask(mask) && isBitFieldInvertedMask(~mask2)
|
||||
// && CountPopulation_32(mask) == CountPopulation_32(~mask2)
|
||||
// && mask == ~mask2
|
||||
// 2b) iff isBitFieldInvertedMask(~mask) && isBitFieldInvertedMask(mask2)
|
||||
// && CountPopulation_32(mask) == CountPopulation_32(~mask2)
|
||||
// && ~mask == mask2
|
||||
// (i.e., copy a bitfield value into another bitfield of the same width)
|
||||
if (N0.getOpcode() != ISD::AND)
|
||||
return SDValue();
|
||||
@ -5289,26 +5290,26 @@ static SDValue PerformORCombine(SDNode *N,
|
||||
return SDValue();
|
||||
unsigned Mask2 = N11C->getZExtValue();
|
||||
|
||||
// Mask and ~Mask2 (or reverse) must be equivalent for the BFI pattern
|
||||
// as is to match.
|
||||
if (ARM::isBitFieldInvertedMask(Mask) &&
|
||||
ARM::isBitFieldInvertedMask(~Mask2) &&
|
||||
(CountPopulation_32(Mask) == CountPopulation_32(~Mask2))) {
|
||||
(Mask == ~Mask2)) {
|
||||
// The pack halfword instruction works better for masks that fit it,
|
||||
// so use that when it's available.
|
||||
if (Subtarget->hasT2ExtractPack() &&
|
||||
(Mask == 0xffff || Mask == 0xffff0000))
|
||||
return SDValue();
|
||||
// 2a
|
||||
unsigned lsb = CountTrailingZeros_32(Mask2);
|
||||
unsigned amt = CountTrailingZeros_32(Mask2);
|
||||
Res = DAG.getNode(ISD::SRL, DL, VT, N1.getOperand(0),
|
||||
DAG.getConstant(lsb, MVT::i32));
|
||||
DAG.getConstant(amt, MVT::i32));
|
||||
Res = DAG.getNode(ARMISD::BFI, DL, VT, N00, Res,
|
||||
DAG.getConstant(Mask, MVT::i32));
|
||||
// Do not add new nodes to DAG combiner worklist.
|
||||
DCI.CombineTo(N, Res, false);
|
||||
return SDValue();
|
||||
} else if (ARM::isBitFieldInvertedMask(~Mask) &&
|
||||
ARM::isBitFieldInvertedMask(Mask2) &&
|
||||
(CountPopulation_32(~Mask) == CountPopulation_32(Mask2))) {
|
||||
(~Mask == Mask2)) {
|
||||
// The pack halfword instruction works better for masks that fit it,
|
||||
// so use that when it's available.
|
||||
if (Subtarget->hasT2ExtractPack() &&
|
||||
@ -5319,7 +5320,7 @@ static SDValue PerformORCombine(SDNode *N,
|
||||
Res = DAG.getNode(ISD::SRL, DL, VT, N00,
|
||||
DAG.getConstant(lsb, MVT::i32));
|
||||
Res = DAG.getNode(ARMISD::BFI, DL, VT, N1.getOperand(0), Res,
|
||||
DAG.getConstant(Mask2, MVT::i32));
|
||||
DAG.getConstant(Mask2, MVT::i32));
|
||||
// Do not add new nodes to DAG combiner worklist.
|
||||
DCI.CombineTo(N, Res, false);
|
||||
return SDValue();
|
||||
|
@ -49,3 +49,14 @@ define i32 @f4(i32 %a) nounwind {
|
||||
%ins12 = or i32 %ins7, 3137
|
||||
ret i32 %ins12
|
||||
}
|
||||
|
||||
; rdar://9177502
|
||||
define i32 @f5(i32 %a, i32 %b) nounwind readnone {
|
||||
entry:
|
||||
; CHECK f5
|
||||
; CHECK-NOT: bfi r0, r2, #0, #1
|
||||
%and = and i32 %a, 2
|
||||
%b.masked = and i32 %b, -2
|
||||
%and3 = or i32 %b.masked, %and
|
||||
ret i32 %and3
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user