[llvm] [SPIRV] Sign-extend operands of sign-sensitive ops on sub-pow2 widths (PR #203661)
Faijul Amin via llvm-commits
llvm-commits at lists.llvm.org
Sat Jul 11 10:45:27 PDT 2026
================
@@ -564,6 +565,83 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
}
for (MachineInstr *MI : TruncToRemove)
MI->eraseFromParent();
+
+ // The widening loop below only retypes registers, so sign-sensitive ops
+ // (G_ASHR, G_SDIV, G_SREM, signed G_ICMP) on sub-pow2 widths see the sign
+ // bit at the wrong position. Emit G_SEXT_INREG; the legalizer lowers it.
+ // TODO: handle vector operands.
+ auto IsSignSensitive = [](const MachineInstr &MI) {
+ switch (MI.getOpcode()) {
+ case TargetOpcode::G_ASHR:
+ case TargetOpcode::G_SDIV:
+ case TargetOpcode::G_SREM:
+ return true;
+ case TargetOpcode::G_ICMP:
+ return CmpInst::isSigned(
+ static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate()));
+ default:
+ return false;
+ }
+ };
+
+ // Per-Reg original width: once we retype a Reg to its widened width,
+ // a later visit can no longer infer the narrow width from MRI. Record
+ // it on first visit so subsequent visits still know to sign-extend.
+ DenseMap<Register, unsigned> OrigWidth;
+ // Per-MI cache so the same vreg used as both operands of a single MI
+ // (e.g. G_ICMP slt %x, %x) gets one shared sext, not two — and so the
+ // second operand isn't left referring to the un-extended Reg after the
+ // first call retypes it.
+ DenseMap<Register, Register> SExtedThisMI;
----------------
mdfaijul wrote:
Yes, it was an overkill. Removed this cache. Reused sign-extended vreg in the refactored code.
https://github.com/llvm/llvm-project/pull/203661
More information about the llvm-commits
mailing list