I see the following ICE (isolated from linux kernel): $ cat kernel.i enum { false, true } a; int b, c, d, e, f; int fn3(); void fn2(); void fn1() { _Bool g, h = false, i = false; int j; c = b && f || d; if (c) { if (d) i = true; _Bool k = b; int l = e, m = a; g = k && l < m || l > m; } if (g) h = true; if (i) fn2(); h &&j &&fn3(); } $ gcc kernel.i -c -O2 during RTL pass: combine kernel.i: In function ‘fn1’: kernel.i:22:1: internal compiler error: in ix86_cc_mode, at config/i386/i386.c:15285 22 | } | ^ 0x783f93 ix86_cc_mode(rtx_code, rtx_def*, rtx_def*) ../../gcc/config/i386/i386.c:15285 0x16d3bef simplify_set ../../gcc/combine.c:6938 0x16d5887 combine_simplify_rtx ../../gcc/combine.c:6440 0x16d74ca subst ../../gcc/combine.c:5719 0x16d7674 subst ../../gcc/combine.c:5581 0x16da961 try_combine ../../gcc/combine.c:3479 0x16e1532 combine_instructions ../../gcc/combine.c:1469 0x16e1532 rest_of_handle_combine ../../gcc/combine.c:15059 0x16e1532 execute ../../gcc/combine.c:15104 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <https://gcc.gnu.org/bugs/> for instructions.
Middle end is asking: (gdb) up #3 0x0000000001621333 in simplify_set (x=0x7fffea968a68) at /home/uros/git/gcc/gcc/combine.c:6938 6938 compare_mode = SELECT_CC_MODE (new_code, op0, op1); (gdb) p new_code $5 = LTGT (gdb) p debug_rtx (op0) (mem/c:SI (symbol_ref:DI ("e") [flags 0x2] <var_decl 0x7ffff7ffbd80 e>) [1 e+0 S4 A32]) $6 = void (gdb) p debug_rtx (op1) (mem/c:SI (symbol_ref:DI ("a") [flags 0x2] <var_decl 0x7ffff7ffbb40 a>) [1 a+0 S4 A32]) $7 = void LTGT is invalid for integer operands.
Just getting started here. But at least CSE seems to be doing exactly what we want. We have this going into cse1: (insn 15 14 16 4 (set (mem/c:SI (symbol_ref:DI ("c") [flags 0x2] <var_decl 0x7f642a835c60 c>) [1 c+0 S4 A32]) (const_int 1 [0x1])) "j.c":9:5 67 {*movsi_internal} (nil)) (insn 16 15 17 4 (set (reg/v:SI 94 [ l ]) (mem/c:SI (symbol_ref:DI ("e") [flags 0x2] <var_decl 0x7f642a835d80 e>) [1 e+0 S4 A32])) "j.c":14:9 67 {*movsi_internal} (nil)) (insn 17 16 18 4 (set (reg/v:SI 95 [ m ]) (mem/c:SI (symbol_ref:DI ("a") [flags 0x2] <var_decl 0x7f642a835b40 a>) [1 a+0 S4 A32])) "j.c":14:16 67 {*movsi_internal} (nil)) (insn 18 17 19 4 (set (reg:CCGC 17 flags) (compare:CCGC (reg/v:SI 94 [ l ]) (reg/v:SI 95 [ m ]))) "j.c":15:16 11 {*cmpsi_1} (nil)) (insn 19 18 20 4 (set (reg:QI 103) (lt:QI (reg:CCGC 17 flags) (const_int 0 [0]))) "j.c":15:16 732 {*setcc_qi} (nil)) (insn 20 19 21 4 (set (reg:CCGC 17 flags) (compare:CCGC (reg/v:SI 94 [ l ]) (reg/v:SI 95 [ m ]))) "j.c":15:20 11 {*cmpsi_1} (nil)) When processing reg18 we record that (reg 17) has the same value as (compare (reg 94) (reg 95)). When we start processing insn 20, we find that equivalence. So if we conceptually replace the RHS of insn 20 with (reg 17) it becomes a nop-set which is now discovered. This results in cse removing insn 20. This is good :-) Introduction of the LTGT happens somewhere in combine. I'm still digging into that.
Got it. simplify-rtx does not validate that a comparison opcode it simplifies to is valid for the mode. Fixing looks trivial. Unfortunately something happened overnight that is causing regressions all over the tester, so I want to fix that first, then throw my simpify-rtx fix into the tester. Regardless, I'll own this. Essentially it has (ior (lt (...)) (gt (...)) and simplifies that to (ltgt (...)) which isn't valid for integer or vector modes.
*** Bug 94144 has been marked as a duplicate of this bug. ***
The master branch has been updated by Jeff Law <law@gcc.gnu.org>: https://gcc.gnu.org/g:75fb811dfaa29d60a897924b0d1629577b90eee7 commit r10-7346-g75fb811dfaa29d60a897924b0d1629577b90eee7 Author: Jeff Law <law@redhat.com> Date: Mon Mar 23 17:55:20 2020 -0600 Verify the code used for the optimized comparison is valid for the comparison's mode. PR rtl-optimization/90275 PR target/94238 PR target/94144 * simplify-rtx.c (comparison_code_valid_for_mode): New function. (simplify_logical_relational_operation): Use it. PR target/94144 PR target/94238 * gcc.c-torture/compile/pr94144.c: New test. * gcc.c-torture/compile/pr94238.c: New test.
Resolved by patch on the trunk.