[llvm] [SLSR] Fix slsr gep stride delta miscompile (PR #204278)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 30 04:32:26 PDT 2026


================
@@ -639,6 +639,63 @@ static void unifyBitWidth(APInt &A, APInt &B) {
     B = B.sext(A.getBitWidth());
 }
 
+// `xor X, signmask` merely flips the sign bit, but ScalarEvolution models it as
+// a non-nsw `add X, signmask`. So a stride `xor X, signmask` and a stride X
+// look like they differ by the constant signmask in the narrow type, even
+// though sext(xor X, signmask) - sext(X) is not that constant (it is +signmask
+// or -signmask depending on the sign of X).
+static bool isXorSignMask(const Value *V) {
+  return match(V, m_Xor(m_Value(), m_SignMask()));
+}
+
+// Whether sign-extending V to a wider type may not distribute over arithmetic,
+// i.e. the narrow value does not sign-extend linearly. This is true for:
+//   - an add/sub/mul/shl that does not carry the `nsw` flag, or
+//   - an `xor X, signmask` (see isXorSignMask).
+static bool mayHaveSignedWrap(const Value *V) {
+  if (isXorSignMask(V))
+    return true;
+  const auto *I = dyn_cast<Instruction>(V);
----------------
fengfeng09 wrote:

Done

https://github.com/llvm/llvm-project/pull/204278


More information about the llvm-commits mailing list