On Tue, Nov 26, 2019 at 07:20:43PM -0600, Segher Boessenkool wrote: > Hi! > > On Wed, Nov 27, 2019 at 12:51:35AM +0100, Jakub Jelinek wrote: > > As mentioned in the PR, on the following testcase we ICE during combine. > > We have (subreg:V1DI (ne:DI (reg:CC flags) (const_int 0)) 0) and > > A subreg of something that is not a reg (or mem, if your port still does > that) is invalid RTL. Where this did come from? Fix that instead?
The testcase has a SUBREG of a REG, try_combine on: i2: (insn 14 13 15 2 (set (subreg:DI (reg:V1DI 96 [ vect_x_12.7 ]) 0) (ne:DI (reg:CCZ 17 flags) (const_int 0 [0]))) "pr92510.c":9:7 701 {*setcc_di_1} (expr_list:REG_DEAD (reg:CCZ 17 flags) (nil))) i3: (insn 15 14 16 2 (parallel [ (set (reg:DI 99) (ior:DI (reg:DI 100) (subreg:DI (reg:V1DI 96 [ vect_x_12.7 ]) 0))) (clobber (reg:CC 17 flags)) ]) "pr92510.c":11:12 454 {*iordi_1} (expr_list:REG_DEAD (reg:DI 100) (expr_list:REG_UNUSED (reg:CC 17 flags) (expr_list:REG_DEAD (reg:V1DI 96 [ vect_x_12.7 ]) (nil))))) and it is just combine subst + simplification that turns it into ... (subreg:DI (subreg:V1DI (ne:DI (reg:CCZ 17 flags) (const_int 0 [0])) 0) 0) ... The restriction that subreg must be of a reg or mem certainly isn't honored in debug_insns (there subregs can be of anything that has non-VOIDmode/BLKmode). Though, just grepping the backends, there are tons of cases where the *.md files have subregs of other rtxes (though as I said, this is not the case of this testcase, there it is created only during substing): config/alpha/alpha.md: (subreg:SI (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ") config/arm/iwmmxt2.md: (subreg:CC (unspec:VMMX [(const_int 0)] UNSPEC_TANDC) 0)) config/arm/iwmmxt2.md: (subreg:CC (unspec:VMMX [(const_int 0)] UNSPEC_TORC) 0)) config/arm/iwmmxt2.md: (subreg:CC (unspec:VMMX [(const_int 0)] UNSPEC_TORVSC) 0)) config/arm/iwmmxt2.md: (subreg:CC (unspec:VMMX [(const_int 0) config/arm/iwmmxt.md: (subreg:TI (vec_concat:V16QI config/arm/iwmmxt.md: (subreg:V8QI (ashiftrt:TI config/arm/iwmmxt.md: (subreg:TI (vec_concat:V16QI config/arm/iwmmxt.md: (subreg:V8QI (ashiftrt:TI config/arm/iwmmxt.md: (subreg:TI (vec_concat:V16QI config/arm/iwmmxt.md: (subreg:V8QI (ashiftrt:TI config/arm/iwmmxt.md: (subreg:TI (vec_concat:V16QI config/arm/iwmmxt.md: (subreg:V8QI (ashiftrt:TI config/arm/iwmmxt.md: (subreg:TI (vec_concat:V16QI config/arm/iwmmxt.md: (subreg:V8QI (ashiftrt:TI config/arm/iwmmxt.md: (subreg:TI (vec_concat:V16QI config/avr/avr.md: (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0")) config/avr/avr.md: (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r")) config/avr/avr.md: (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0") config/avr/avr.md: (subreg:QI (lo_sum:PSI (match_operand:QI 1 "nonmemory_operand" "ri") config/avr/avr.md: (and:QI (subreg:QI (any_shiftrt:HISI (match_operand:HISI 1 "register_operand" "r") config/h8300/h8300.md: (subreg:QI (lshiftrt:HI (match_operand:HI 1 "register_operand" "r") config/h8300/h8300.md: (subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") config/h8300/h8300.md: (subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") config/h8300/h8300.md: (subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") config/m32c/bitops.md: (ior:QI (subreg:QI (ashift:HI (const_int 1) config/m68k/m68k.md: (subreg:HI (ashiftrt:DI (match_operand:DI 1 "general_operand" "ro") config/m68k/m68k.md: (subreg:SI (ashiftrt:DI (match_operand:DI 1 "general_operand" "ro") config/m68k/m68k.md: (subreg:SI (lshiftrt:DI (match_operand:DI 1 "general_operand" "ro") config/m68k/m68k.md: (ior:QI (subreg:QI (ashift:SI (const_int 1) config/m68k/m68k.md: (ior:QI (subreg:QI (ashift:SI (const_int 1) config/msp430/msp430.md: (subreg:PSI (zero_extend:SI (match_operand:HI 1 "general_operand" "0,r")) 0))] config/msp430/msp430.md: (subreg:PSI (sign_extend:SI (match_operand:HI 1 "general_operand" "0")) 0))] config/riscv/riscv.md: (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" " r,r") config/riscv/riscv.md: (subreg:SI (neg:DI (match_operand:DI 1 "register_operand" " r")) config/s390/s390.md: (subreg:SI (lshiftrt:DI config/s390/s390.md: (subreg:SI (clz:DI (match_dup 1)) 4)))))) config/sh/sh.md: (subreg:SI (zero_extract:DI (match_operand:SI 0 "arith_reg_operand") config/sh/sh.md: (subreg:SI (zero_extract:DI (match_operand:SI 0 "arith_reg_operand") config/sparc/sparc.md: (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") config/sparc/sparc.md: (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") config/sparc/sparc.md: (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r") config/sparc/sparc.md: (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r") config/sparc/sparc.md: (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") config/v850/v850.md: (subreg:QI (ior:SI (subreg:SI (match_dup 0) 0) config/v850/v850.md: (subreg:HI (ior:SI (subreg:SI (match_dup 0) 0) config/v850/v850.md: (subreg:QI (xor:SI (subreg:SI (match_dup 0) 0) config/v850/v850.md: (subreg:HI (xor:SI (subreg:SI (match_dup 0) 0) > > gen_lowpart_for_combine turns that into (ne:V1DI (reg:CC flags) (const_int > > 0)) > > which looks wrong to me, > > Why would that be wrong? Because (reg:CC flags) (const_int 0) comparison computes a scalar (boolean), not a vector, for vector comparisons I think we only allow say: (ne:V1DI (reg:V1DI ...) (reg:V1DI ...)) or const_vector as the other operand. Sure, V1*mode vectors are weird vectors, but still are vectors. If we talk about V4DImode, it should be clearer that something that produces a scalar can't have vector mode. Jakub