From 8834502ce4d47b7088b48f21360934a589f8fb12 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sat, 27 Dec 2025 11:45:18 +0100 Subject: [PATCH] simplify-rtx: Fix up (ne (ior (ne x 0) y) 0) simplification [PR123114] The following testcase ICEs on x86_64-linux since the PR52345 (ne (ior (ne x 0) y) 0) simplification was (slightly) fixed. It wants to optimize (set (reg/i:DI 10 a0) (ne:DI (ior:DI (ne:DI (reg:DI 151 [ a ]) (const_int 0 [0])) (reg:DI 152 [ b ])) (const_int 0 [0]))) but doesn't check important property of that, in particular that the mode of the inner NE operand is the same as the mode of the inner NE. The following testcase has (set (reg:CCZ 17 flags) (compare:CCZ (ior:QI (ne:QI (reg/v:SI 104 [ c ]) (const_int 0 [0])) (reg:QI 98 [ _5 ])) (const_int 0 [0]))) where cmp_mode is QImode, but the mode of the inner NE operand is SImode instead, and it attempts to create (ne:CCZ (ior:QI (reg/v:SI 104 [ c ]) (reg:QI 98 [ _5 ])) (const_int 0)) which obviously crashes later on. The following patch fixes it by checking the mode of the inner NE operand and also by using CONST0_RTX (cmp_mode) instead of CONST0_RTX (mode) because that is the mode of the other operand, not mode which is the mode of the outer comparison (though, guess for most modes it will still be const0_rtx). I guess for mode mismatches we could arbitrarily choose some extension (zero or sign) and extend the narrower mode to the wider mode, but I doubt that it would ever match on any target. But even then we'd need to limit it, we wouldn't want to deal with another mode class (say floating point comparisons), and dunno about vector modes etc. 2025-12-27 Jakub Jelinek PR rtl-optimization/123114 * simplify-rtx.cc (simplify_context::simplify_relational_operation): Verify XEXP (XEXP (op0, 0), 0) mode and use CONST0_RTX (cmp_mode) instead of CONST0_RTX (mode). * gcc.dg/pr123114.c: New test. --- gcc/simplify-rtx.cc | 3 ++- gcc/testsuite/gcc.dg/pr123114.c | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/pr123114.c diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc index 8016e02e925..38d366622b5 100644 --- a/gcc/simplify-rtx.cc +++ b/gcc/simplify-rtx.cc @@ -6509,8 +6509,9 @@ simplify_context::simplify_relational_operation_1 (rtx_code code, /* only enters if op1 is 0 */ /* Verify IOR operand is NE */ && GET_CODE (XEXP (op0, 0)) == NE + && GET_MODE (XEXP (XEXP (op0, 0), 0)) == cmp_mode /* Verify second NE operand is 0 */ - && XEXP (XEXP (op0, 0), 1) == CONST0_RTX (mode)) + && XEXP (XEXP (op0, 0), 1) == CONST0_RTX (cmp_mode)) { rtx t = gen_rtx_IOR (cmp_mode, XEXP (XEXP (op0, 0), 0), XEXP (op0, 1)); t = gen_rtx_fmt_ee (code, mode, t, CONST0_RTX (mode)); diff --git a/gcc/testsuite/gcc.dg/pr123114.c b/gcc/testsuite/gcc.dg/pr123114.c new file mode 100644 index 00000000000..3d36305e576 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr123114.c @@ -0,0 +1,21 @@ +/* PR rtl-optimization/123114 */ +/* { dg-do compile } */ +/* { dg-options "-O3 -fno-tree-vrp" } */ + +volatile int a, b, g; +unsigned short e; +int f; + +int +main () +{ + int c, d; + while (a) + { + c = e = b << 2; + d = f; + g = (c <= 0 && d) || c ? 0 : d; + a = g; + } + return 0; +} -- 2.43.0