[llvm] [GlobalISel] Use G_ANYEXT instead of G_ZEXT for shift amount widening (PR #223136)
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Sat Sep 12 21:09:17 PDT 2026
================
@@ -3044,9 +3044,10 @@ LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) {
widenScalarDst(MI, WideTy);
} else {
assert(TypeIdx == 1);
- // The "number of bits to shift" operand must preserve its value as an
- // unsigned integer:
- widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ZEXT);
+ // The shift amount is undefined behavior for values >= type width,
+ // so we can use G_ANYEXT instead of G_ZEXT to avoid generating
+ // a redundant AND instruction.
----------------
topperc wrote:
The semantics of the G_SHL, etc. nodes are the all bits of the shift amounts are used. Using G_ANYEXT will make the upper bits undefined. If some optimization causes them to become provably non-zero, then the shift would appear to be undefined and be deleted.
SelectionDAG does not do this and does use ZERO_EXTEND. Removal of the unnecessary AND is handled at isel time in SelectionDAG on at least RISC-V, X86, and AArch64.
https://github.com/llvm/llvm-project/pull/223136
More information about the llvm-commits
mailing list