aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndrew Pinski <quic_apinski@quicinc.com>2025-05-02 09:46:24 -0700
committerAndrew Pinski <quic_apinski@quicinc.com>2025-05-02 15:13:37 -0700
commitdba5d112691a3e10b722468d94fffeda0fdbb818 (patch)
tree1a02922e8d1e5e98bdb3919108669029440a6419 /gcc
parente81f2f4855876c5d85ab9870c5a150ee1a59ee73 (diff)
downloadgcc-dba5d112691a3e10b722468d94fffeda0fdbb818.zip
gcc-dba5d112691a3e10b722468d94fffeda0fdbb818.tar.gz
gcc-dba5d112691a3e10b722468d94fffeda0fdbb818.tar.bz2
simplify-rtl: Fix crash due to simplify_with_subreg_not [PR120059]
r16-286-gd84fbc516ea57d added a call to simplify_gen_subreg but didn't check if the result of simplify_gen_subreg was non-null. simplify_gen_subreg can return NULL if the subreg would be not valid. In the case below we had a hard register for the SSE register xmm0 of mode SI and doing a subreg to QI mode but QImode is not a valid mode for the SSE register so simplify_gen_subreg would return NULL. This adds the obvious check. Pushed as obvious after bootstrap/test on x86_64-linux-gnu. PR rtl-optimization/120059 gcc/ChangeLog: * simplify-rtx.cc (simplify_with_subreg_not): Check the result of simplify_gen_subreg. gcc/testsuite/ChangeLog: * gcc.dg/torture/pr120059-1.c: New test. Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/simplify-rtx.cc4
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr120059-1.c17
2 files changed, 21 insertions, 0 deletions
diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
index 7c4d8e6..7bcbe11 100644
--- a/gcc/simplify-rtx.cc
+++ b/gcc/simplify-rtx.cc
@@ -3063,6 +3063,10 @@ simplify_with_subreg_not (rtx_code binop, machine_mode mode, rtx op0, rtx op1)
XEXP (SUBREG_REG (opn), 0),
GET_MODE (SUBREG_REG (opn)),
SUBREG_BYTE (opn));
+
+ if (!new_subreg)
+ return NULL_RTX;
+
rtx new_not = simplify_gen_unary (NOT, mode, new_subreg, mode);
if (opn == op0)
return simplify_gen_binary (binop, mode, new_not, op1);
diff --git a/gcc/testsuite/gcc.dg/torture/pr120059-1.c b/gcc/testsuite/gcc.dg/torture/pr120059-1.c
new file mode 100644
index 0000000..36d0c5b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr120059-1.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-g" } */
+
+/* PR rtl-optimization/120059 */
+
+int a[4];
+int c, d;
+void f(void) {
+ for (int e = 0; e < 4; e++)
+ a[e] = e | c;
+ int b = 0;
+ if ((a[0] & 1) && (a[0] & 4))
+ b = 2;
+ if (a[0] & 16)
+ b |= 1;
+ d = ~b;
+}