[llvm] [AMDGPU][ISel] `setcc` peephole for comparisons with upper 32 bits of a 64-bit register pair (PR #177662)
Jay Foad via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 28 09:02:34 PST 2026
================
@@ -16852,6 +16849,58 @@ SDValue SITargetLowering::performSetCCCombine(SDNode *N,
return LHS.getOperand(0);
}
}
+
+ // Fold setcc patterns which test only upper 32 bits of operand
+ // hi64 = v.64 & 0x????'????'0000'0000
+ // setcc hi64, (x.32 << 32), op
+ // =>
+ // mask.32 = v.hi32 & 0x????'????
+ // setcc mask.32, x.32, op
+ if (VT == MVT::i64) {
+ const uint64_t CRHSInt = CRHSVal.getZExtValue();
+
+ const uint64_t Mask32 = maskTrailingOnes<uint64_t>(32);
+ const uint64_t Bit32 = Mask32 + 1;
+
+ ISD::CondCode HiCC = ISD::SETCC_INVALID;
+ uint32_t HiConstant = 0;
+
+ // Handle special case of comparisons with 1 << 32 or (1 << 32) - 1
+ // In this case, isolating the higher bits of v.64 with a mask are not
+ // necessary.
+ //
+ // setcc v.64, 0x1'0000'0000, ult => setcc v.hi32, 0, eq
+ // setcc v.64, 0x1'0000'0000, uge => setcc v.hi32, 0, ne
+ // setcc v.64, 0xffff'ffff, ule => setcc v.hi32, 0, eq
+ // setcc v.64, 0xffff'ffff, ugt => setcc v.hi32, 0, ne
----------------
jayfoad wrote:
A better (simpler) way to express this is:
```suggestion
// setcc v.64, 0x1'0000'0000, ult => setcc v.hi32, 1, ult
// setcc v.64, 0x1'0000'0000, uge => setcc v.hi32, 1, uge
// setcc v.64, 0xffff'ffff, ule => setcc v.hi32, 0, ule
// setcc v.64, 0xffff'ffff, ugt => setcc v.hi32, 0, ugt
```
Then note that in all cases the cond code is unchanged and the 32-bit constant is just the high part of the 64-bit constant.
Then the ult/uge cases generalize to any constant whose low part is 0, and can also include slt/sge.
The ule/ugt cases generalize to any constant whose low part is 0xffffffff, and can also include sle/sgt.
https://github.com/llvm/llvm-project/pull/177662
More information about the llvm-commits
mailing list