@@ -16502,12 +16502,57 @@ static void knownBitsForWorkitemID(const GCNSubtarget &ST,
16502
16502
Known.Zero.setHighBits(llvm::countl_zero(MaxValue));
16503
16503
}
16504
16504
16505
+ static void knownBitsForSBFE(const MachineInstr &MI, GISelValueTracking &VT,
16506
+ KnownBits &Known, const APInt &DemandedElts,
16507
+ unsigned BFEWidth, bool SExt) {
16508
+ const MachineRegisterInfo &MRI = VT.getMachineFunction().getRegInfo();
16509
+ const MachineOperand &Src1 = MI.getOperand(2);
16510
+
16511
+ unsigned Src1Cst = 0;
16512
+ if (Src1.isImm())
16513
+ Src1Cst = Src1.getImm();
16514
+ else if (Src1.isReg()) {
16515
+ auto Cst = getIConstantVRegValWithLookThrough(Src1.getReg(), MRI);
16516
+ if (!Cst)
16517
+ return;
16518
+ Src1Cst = Cst->Value.getZExtValue();
16519
+ } else
16520
+ return;
16521
+
16522
+ const unsigned Mask = maskTrailingOnes<unsigned>(6);
16523
+ const unsigned Offset = Src1Cst & Mask;
16524
+ const unsigned Width = (Src1Cst >> 16) & Mask;
16525
+
16526
+ VT.computeKnownBitsImpl(MI.getOperand(1).getReg(), Known, DemandedElts);
16527
+
16528
+ const uint64_t WidthMask = maskTrailingOnes<uint64_t>(Width);
16529
+ Known.Zero = Known.Zero.shl(Offset) & WidthMask;
16530
+ Known.One = Known.One.shl(Offset) & WidthMask;
16531
+
16532
+ if (SExt)
16533
+ Known.sextInReg(Width);
16534
+ else
16535
+ Known.Zero |= maskLeadingOnes<unsigned>(BFEWidth - Width);
16536
+ }
16537
+
16505
16538
void SITargetLowering::computeKnownBitsForTargetInstr(
16506
16539
GISelValueTracking &VT, Register R, KnownBits &Known,
16507
16540
const APInt &DemandedElts, const MachineRegisterInfo &MRI,
16508
16541
unsigned Depth) const {
16509
16542
const MachineInstr *MI = MRI.getVRegDef(R);
16510
16543
switch (MI->getOpcode()) {
16544
+ case AMDGPU::S_BFE_I32:
16545
+ return knownBitsForSBFE(*MI, VT, Known, DemandedElts, /*Width=*/32,
16546
+ /*SExt=*/true);
16547
+ case AMDGPU::S_BFE_U32:
16548
+ return knownBitsForSBFE(*MI, VT, Known, DemandedElts, /*Width=*/32,
16549
+ /*SExt=*/false);
16550
+ case AMDGPU::S_BFE_I64:
16551
+ return knownBitsForSBFE(*MI, VT, Known, DemandedElts, /*Width=*/64,
16552
+ /*SExt=*/true);
16553
+ case AMDGPU::S_BFE_U64:
16554
+ return knownBitsForSBFE(*MI, VT, Known, DemandedElts, /*Width=*/64,
16555
+ /*SExt=*/false);
16511
16556
case AMDGPU::G_INTRINSIC:
16512
16557
case AMDGPU::G_INTRINSIC_CONVERGENT: {
16513
16558
Intrinsic::ID IID = cast<GIntrinsic>(MI)->getIntrinsicID();
0 commit comments