mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-14 15:19:33 +00:00
[AArch64] Fix a corner case in BitFeild select
Summary: When not useful bits, BitWidth becomes 0 and APInt will not be happy. See https://llvm.org/bugs/show_bug.cgi?id=25571 We can just mark the operand as IMPLICIT_DEF is none bits of it is used. Reviewers: t.p.northover, jmolloy Subscribers: gberry, jmolloy, mgrang, aemerson, llvm-commits, rengolin Differential Revision: http://reviews.llvm.org/D14803 llvm-svn: 254440
This commit is contained in:
parent
8a9536c837
commit
6501fb731e
@ -1974,7 +1974,8 @@ static bool isBitfieldPositioningOp(SelectionDAG *CurDAG, SDValue Op,
|
||||
// f = Opc Opd0, Opd1, LSB, MSB ; where Opc is a BFM, LSB = imm, and MSB = imm2
|
||||
static bool isBitfieldInsertOpFromOr(SDNode *N, unsigned &Opc, SDValue &Dst,
|
||||
SDValue &Src, unsigned &ImmR,
|
||||
unsigned &ImmS, SelectionDAG *CurDAG) {
|
||||
unsigned &ImmS, const APInt &UsefulBits,
|
||||
SelectionDAG *CurDAG) {
|
||||
assert(N->getOpcode() == ISD::OR && "Expect a OR operation");
|
||||
|
||||
// Set Opc
|
||||
@ -1988,8 +1989,6 @@ static bool isBitfieldInsertOpFromOr(SDNode *N, unsigned &Opc, SDValue &Dst,
|
||||
|
||||
// Because of simplify-demanded-bits in DAGCombine, involved masks may not
|
||||
// have the expected shape. Try to undo that.
|
||||
APInt UsefulBits;
|
||||
getUsefulBits(SDValue(N, 0), UsefulBits);
|
||||
|
||||
unsigned NumberOfIgnoredLowBits = UsefulBits.countTrailingZeros();
|
||||
unsigned NumberOfIgnoredHighBits = UsefulBits.countLeadingZeros();
|
||||
@ -2083,11 +2082,18 @@ SDNode *AArch64DAGToDAGISel::SelectBitfieldInsertOp(SDNode *N) {
|
||||
unsigned Opc;
|
||||
unsigned LSB, MSB;
|
||||
SDValue Opd0, Opd1;
|
||||
EVT VT = N->getValueType(0);
|
||||
APInt NUsefulBits;
|
||||
getUsefulBits(SDValue(N, 0), NUsefulBits);
|
||||
|
||||
if (!isBitfieldInsertOpFromOr(N, Opc, Opd0, Opd1, LSB, MSB, CurDAG))
|
||||
// If all bits are not useful, just return UNDEF.
|
||||
if (!NUsefulBits)
|
||||
return CurDAG->SelectNodeTo(N, TargetOpcode::IMPLICIT_DEF, VT);
|
||||
|
||||
if (!isBitfieldInsertOpFromOr(N, Opc, Opd0, Opd1, LSB, MSB, NUsefulBits,
|
||||
CurDAG))
|
||||
return nullptr;
|
||||
|
||||
EVT VT = N->getValueType(0);
|
||||
SDLoc dl(N);
|
||||
SDValue Ops[] = { Opd0,
|
||||
Opd1,
|
||||
|
@ -215,3 +215,25 @@ define void @test_32bit_opnd1_better(i32* %existing, i32* %new) {
|
||||
|
||||
ret void
|
||||
}
|
||||
|
||||
; Tests when all the bits from one operand are not useful
|
||||
define i32 @test_nouseful_bits(i8 %a, i32 %b) {
|
||||
; CHECK-LABEL: test_nouseful_bits:
|
||||
; CHECK: bfi
|
||||
; CHECK: bfi
|
||||
; CHECK: bfi
|
||||
; CHECK-NOT: bfi
|
||||
; CHECK-NOT: or
|
||||
; CHECK: lsl
|
||||
%conv = zext i8 %a to i32 ; 0 0 0 A
|
||||
%shl = shl i32 %b, 8 ; B2 B1 B0 0
|
||||
%or = or i32 %conv, %shl ; B2 B1 B0 A
|
||||
%shl.1 = shl i32 %or, 8 ; B1 B0 A 0
|
||||
%or.1 = or i32 %conv, %shl.1 ; B1 B0 A A
|
||||
%shl.2 = shl i32 %or.1, 8 ; B0 A A 0
|
||||
%or.2 = or i32 %conv, %shl.2 ; B0 A A A
|
||||
%shl.3 = shl i32 %or.2, 8 ; A A A 0
|
||||
%or.3 = or i32 %conv, %shl.3 ; A A A A
|
||||
%shl.4 = shl i32 %or.3, 8 ; A A A 0
|
||||
ret i32 %shl.4
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user