[llvm] 3ef5046 - [CodeGen] Fix crash matching a negated implicit complex multiply (#217650)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 21 02:20:53 PDT 2026
Author: Igor Kirillov
Date: 2026-08-21T10:20:48+01:00
New Revision: 3ef5046670c087c3ed7ced1d32e608f8a11d3e4a
URL: https://github.com/llvm/llvm-project/commit/3ef5046670c087c3ed7ced1d32e608f8a11d3e4a
DIFF: https://github.com/llvm/llvm-project/commit/3ef5046670c087c3ed7ced1d32e608f8a11d3e4a.diff
LOG: [CodeGen] Fix crash matching a negated implicit complex multiply (#217650)
identifyNodeWithImplicitAdd used Op after checking I0 with isNeg(),
which does not populate Op. When no earlier matcher initialized Op,
subsequent matching could dereference an invalid Value pointer and crash
the compiler.
Added:
llvm/test/CodeGen/AArch64/complex-deinterleaving-negation.ll
Modified:
llvm/lib/CodeGen/ComplexDeinterleavingPass.cpp
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/ComplexDeinterleavingPass.cpp b/llvm/lib/CodeGen/ComplexDeinterleavingPass.cpp
index 513c7782630ac..b02987dec3776 100644
--- a/llvm/lib/CodeGen/ComplexDeinterleavingPass.cpp
+++ b/llvm/lib/CodeGen/ComplexDeinterleavingPass.cpp
@@ -668,7 +668,7 @@ ComplexDeinterleavingGraph::identifyNodeWithImplicitAdd(
if (isNeg(I0)) {
Negs |= 2;
Negs ^= 1;
- I0 = Op;
+ I0 = getNegOperand(I0);
} else if (match(I1, m_Neg(m_Value(Op)))) {
Negs |= 2;
Negs ^= 1;
diff --git a/llvm/test/CodeGen/AArch64/complex-deinterleaving-negation.ll b/llvm/test/CodeGen/AArch64/complex-deinterleaving-negation.ll
new file mode 100644
index 0000000000000..f590805fd9ed5
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/complex-deinterleaving-negation.ll
@@ -0,0 +1,34 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s --mattr=+complxnum,+neon -o - | FileCheck %s
+
+target triple = "aarch64"
+
+; Check that a negated first operand of the imaginary partial product is
+; recognized as part of a complex multiplication.
+define <4 x double> @complex_mul_negated_imaginary_operand(<4 x double> %a, <4 x double> %b) {
+; CHECK-LABEL: complex_mul_negated_imaginary_operand:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: movi v4.2d, #0000000000000000
+; CHECK-NEXT: movi v5.2d, #0000000000000000
+; CHECK-NEXT: fcmla v5.2d, v2.2d, v0.2d, #270
+; CHECK-NEXT: fcmla v4.2d, v3.2d, v1.2d, #270
+; CHECK-NEXT: fcmla v5.2d, v2.2d, v0.2d, #0
+; CHECK-NEXT: fcmla v4.2d, v3.2d, v1.2d, #0
+; CHECK-NEXT: mov v0.16b, v5.16b
+; CHECK-NEXT: mov v1.16b, v4.16b
+; CHECK-NEXT: ret
+entry:
+ %a.real = shufflevector <4 x double> %a, <4 x double> poison, <2 x i32> <i32 0, i32 2>
+ %a.imag = shufflevector <4 x double> %a, <4 x double> poison, <2 x i32> <i32 1, i32 3>
+ %b.real = shufflevector <4 x double> %b, <4 x double> poison, <2 x i32> <i32 0, i32 2>
+ %b.imag = shufflevector <4 x double> %b, <4 x double> poison, <2 x i32> <i32 1, i32 3>
+ %neg.a.real = fneg contract <2 x double> %a.real
+ %real.0 = fmul contract <2 x double> %a.imag, %b.imag
+ %real.1 = fmul contract <2 x double> %a.real, %b.real
+ %real = fadd contract <2 x double> %real.0, %real.1
+ %imag.0 = fmul contract <2 x double> %neg.a.real, %b.imag
+ %imag.1 = fmul contract <2 x double> %a.imag, %b.real
+ %imag = fadd contract <2 x double> %imag.0, %imag.1
+ %interleaved = shufflevector <2 x double> %real, <2 x double> %imag, <4 x i32> <i32 0, i32 2, i32 1, i32 3>
+ ret <4 x double> %interleaved
+}
More information about the llvm-commits
mailing list