[llvm] [SLSR] Fix slsr gep stride delta miscompile (PR #204278)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 29 23:26:40 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);
+ if (!I)
+ return false;
----------------
arsenm wrote:
The name and direction of this function feels backwards. Generally the unrecognized cases should be treated conservatively
https://github.com/llvm/llvm-project/pull/204278
More information about the llvm-commits
mailing list