[DAG] computeKnownBits - add basic shift-by-parts handling

Concat KnownBits from ISD::SHL_PARTS / ISD::SRA_PARTS / ISD::SRL_PARTS lo/hi operands and perform the KnownBits calculation by the shift amount on the extended type, before splitting the KnownBits based on the requested lo/hi result.
This commit is contained in:
Simon Pilgrim 2022-07-23 09:46:30 +01:00
parent 380a1b204c
commit 8937252465
2 changed files with 33 additions and 1 deletions

View file

@ -3337,6 +3337,38 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
Known.Zero |= Known2.Zero;
}
break;
case ISD::SHL_PARTS:
case ISD::SRA_PARTS:
case ISD::SRL_PARTS: {
assert((Op.getResNo() == 0 || Op.getResNo() == 1) && "Unknown result");
// Collect lo/hi source values and concatenate.
// TODO: Would a KnownBits::concatBits helper be useful?
unsigned LoBits = Op.getOperand(0).getScalarValueSizeInBits();
unsigned HiBits = Op.getOperand(1).getScalarValueSizeInBits();
Known = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
Known2 = computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1);
Known = Known.anyext(LoBits + HiBits);
Known.insertBits(Known2, LoBits);
// Collect shift amount.
Known2 = computeKnownBits(Op.getOperand(2), DemandedElts, Depth + 1);
if (Opcode == ISD::SHL_PARTS)
Known = KnownBits::shl(Known, Known2);
else if (Opcode == ISD::SRA_PARTS)
Known = KnownBits::ashr(Known, Known2);
else // if (Opcode == ISD::SRL_PARTS)
Known = KnownBits::lshr(Known, Known2);
// TODO: Minimum shift low/high bits are known zero.
if (Op.getResNo() == 0)
Known = Known.extractBits(LoBits, 0);
else
Known = Known.extractBits(HiBits, LoBits);
break;
}
case ISD::SIGN_EXTEND_INREG: {
Known = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
EVT EVT = cast<VTSDNode>(Op.getOperand(1))->getVT();

View file

@ -19,7 +19,7 @@ define i32 @int87(i32 %uint64p_8, i1 %cond) nounwind {
; CHECK-NEXT: testb $64, %dl
; CHECK-NEXT: movq %rcx, %rsi
; CHECK-NEXT: cmovneq %rax, %rsi
; CHECK-NEXT: orl $0, %esi
; CHECK-NEXT: testl %esi, %esi
; CHECK-NEXT: je .LBB0_1
; CHECK-NEXT: # %bb.2: # %if.then
; CHECK-NEXT: movl $1, %eax