llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-x86

Author: Muhammad Mahdi Amirpour (m-amirpour)

<details>
<summary>Changes</summary>

Fixes #<!-- -->233063.

`LowerFunnelShift`'s pre-AVX2 256-bit split path calls
`DAG.getNode(FSHL/FSHR, ...)` and then `splitVectorOp` on the result. When
all operands are constants — e.g. `ucmp(x, x)` expanded to a zero vector
by the vector legalizer — `getNode` constant-folds the funnel shift into a
`BUILD_VECTOR`. `splitVectorOp` then treats the 8 scalar `BUILD_VECTOR`
operands as sub-vectors, producing a malformed `v4i32 BUILD_VECTOR` with
8 operands:

- **+asserts**: `Assertion 'VT.getVectorNumElements() == (unsigned)NumOps
  &amp;&amp; "Incorrect element count in BUILD_VECTOR!"' failed.`
- **Release**: `free(): invalid size` (heap corruption).

Bail out to the generic path when the node was constant-folded.

## Test

- Reproducer from the issue: `llc -O2 -mattr=+avx crash-min.ll -o /dev/null`
  - before: assertion / SIGABRT
  - after: exits 0
- New regression test: `llvm/test/CodeGen/X86/funnel-shift-avx-constant-fold.ll`
- `ninja check-llvm-codegen-x86`: 5762 tests, 0 failures
  (5745 pass, 15 XFAIL, 2 unsupported)
- `clang-format`: no changes

---
Full diff: https://github.com/llvm/llvm-project/pull/233070.diff


3 Files Affected:

- (modified) clang/test/SemaCXX/cxx2c-fold-exprs.cpp (+15) 
- (modified) llvm/lib/Target/X86/X86ISelLowering.cpp (+9) 
- (added) llvm/test/CodeGen/X86/funnel-shift-avx-constant-fold.ll (+22) 


``````````diff
diff --git a/clang/test/SemaCXX/cxx2c-fold-exprs.cpp 
b/clang/test/SemaCXX/cxx2c-fold-exprs.cpp
index f0819ed04881b3..0778ed7fe66372 100644
--- a/clang/test/SemaCXX/cxx2c-fold-exprs.cpp
+++ b/clang/test/SemaCXX/cxx2c-fold-exprs.cpp
@@ -752,3 +752,18 @@ static_assert(count == 2);
 
 }
 
+namespace GH205000 {
+
+template <int N>
+struct StringLiteral {
+  constexpr StringLiteral(const auto... c)
+    requires (__is_same(decltype(c), const char) && ...) {}
+  constexpr StringLiteral(const char (&s)[N]) {}
+};
+
+template <StringLiteral... fields>
+struct Lit {};
+
+using Unit = Lit<"a">;
+
+}
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp 
b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 416761793904f9..d5ec8d9f3704b6 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -32290,7 +32290,16 @@ static SDValue LowerFunnelShift(SDValue Op, const 
X86Subtarget &Subtarget,
         (VT.is512BitVector() && !Subtarget.useBWIRegs() &&
          EltSizeInBits < 32)) {
       // Pre-mask the amount modulo using the wider vector.
+      unsigned OrigOpc = Op.getOpcode();
       Op = DAG.getNode(Op.getOpcode(), DL, VT, Op0, Op1, AmtMod);
+
+      // If constant folding turned the funnel shift into a BUILD_VECTOR (e.g.
+      // ucmp(x, x) was expanded to a zero vector by the legalizer), don't try
+      // to split a non-funnel-shift node: its operands are scalars, not
+      // sub-vectors. Let the generic legalizer handle it instead.
+      if (Op.getOpcode() != OrigOpc)
+        return Op;
+
       return splitVectorOp(Op, DAG, DL);
     }
 
diff --git a/llvm/test/CodeGen/X86/funnel-shift-avx-constant-fold.ll 
b/llvm/test/CodeGen/X86/funnel-shift-avx-constant-fold.ll
new file mode 100644
index 00000000000000..db5cceeb9faed6
--- /dev/null
+++ b/llvm/test/CodeGen/X86/funnel-shift-avx-constant-fold.ll
@@ -0,0 +1,22 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 
UTC_ARGS: --version 5
+; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx | FileCheck %s
+
+; Regression test for https://github.com/llvm/llvm-project/issues/233063
+; LowerFunnelShift's pre-AVX2 256-bit split path called splitVectorOp on a
+; node that constant-folded into a BUILD_VECTOR, producing a malformed
+; v4i32 BUILD_VECTOR with 8 scalar operands (assert, or heap corruption in
+; Release builds).
+
+define <8 x i32> @fshr_constant_fold(<8 x i32> %x) {
+; CHECK-LABEL: fshr_constant_fold:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    vmovaps {{.*#+}} ymm0 = [8,8,24,16,40,24,56,32]
+; CHECK-NEXT:    retq
+  %v0 = call <8 x i32> @llvm.ucmp.v8i32.v8i32(<8 x i32> %x, <8 x i32> %x)
+  %v1 = call <8 x i32> @llvm.fshr.v8i32(<8 x i32> %v0, <8 x i32> <i32 16, i32 
32, i32 48, i32 64, i32 80, i32 96, i32 112, i32 128>,
+                                        <8 x i32> <i32 1, i32 2, i32 1, i32 2, 
i32 1, i32 2, i32 1, i32 2>)
+  ret <8 x i32> %v1
+}
+
+declare <8 x i32> @llvm.ucmp.v8i32.v8i32(<8 x i32>, <8 x i32>)
+declare <8 x i32> @llvm.fshr.v8i32(<8 x i32>, <8 x i32>, <8 x i32>)

``````````

</details>


https://github.com/llvm/llvm-project/pull/233070
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to