From 07da9b7f13c92a21d12172a9df85ad762591b998 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Sun, 19 Nov 2023 11:56:57 -0700 Subject: [PATCH] [committed] Fix missing mode on a few unspec/unspec_volatile operands This is fix for a minor problem Jivan and I found while testing the ext-dce work originally from Joern. The ext-dce pass will transform zero/sign extensions into subreg accesses when the upper bits are actually unused. So it's more likely with the ext-dce work to get a sequence like this prior to combine: > >> (insn 10 9 11 2 (set (reg:SI 144) >> (unspec_volatile [ >> (const_int 0 [0]) >> ] UNSPECV_FRFLAGS)) "j.c":11:3 discrim 1 362 {riscv_frflags} >> (nil)) >> (insn 11 10 55 2 (set (reg:DI 140 [ _12 ]) >> (subreg:DI (reg:SI 144) 0)) "j.c":11:3 discrim 1 206 {*movdi_64bit} >> (expr_list:REG_DEAD (reg:SI 144) >> (nil))) When we try to combine insn 10->11 we'll ultimately call simplify_subreg with something like (subreg:DI (unspec_volatile [...]) 0) Note the lack of a mode on the unspec_volatile. That in turn will cause simplify_subreg to trigger an assertion. The modeless unspec is generated by the RISC-V backend and the more I've pondered this issue over the last few days the more I'm convinced it's a backend bug. Basically if the LHS of the set has a mode, then the RHS of the set should have a mode as well. I've audited the various backends and only found a few problems which are fixed by this patch. I've tested the relevant ports in my tester. c6x, sh, mips and s390[x]. There are other patterns that are potentially problematical in various ports. They have a REG destination and an UNSPEC source, but the REG has no mode in the pattern. Since it wasn't clear what mode to give the UNSPEC, I left those alone. gcc/ * config/c6x/c6x.md (mvilc): Add mode to UNSPEC source. * config/mips/mips.md (rdhwr_synci_step_): Likewise. * config/riscv/riscv.md (riscv_frcsr, riscv_frflags): Likewise. * config/s390/s390.md (@split_stack_call): Likewise. (@split_stack_cond_call): Likewise. * config/sh/sh.md (sp_switch_1): Likewise. --- gcc/config/c6x/c6x.md | 2 +- gcc/config/mips/mips.md | 2 +- gcc/config/riscv/riscv.md | 4 ++-- gcc/config/s390/s390.md | 12 ++++++------ gcc/config/sh/sh.md | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/gcc/config/c6x/c6x.md b/gcc/config/c6x/c6x.md index 88b9291ae236..906fdb34a82e 100644 --- a/gcc/config/c6x/c6x.md +++ b/gcc/config/c6x/c6x.md @@ -1440,7 +1440,7 @@ (define_insn "mvilc" [(set (reg:SI REG_ILC) - (unspec [(match_operand:SI 0 "register_operand" "a,b")] UNSPEC_MVILC))] + (unspec:SI [(match_operand:SI 0 "register_operand" "a,b")] UNSPEC_MVILC))] "TARGET_INSNS_64PLUS" "%|%.\\tmvc\\t%$\\t%0, ILC" [(set_attr "predicable" "no") diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index a25454783fbf..0666310734e3 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -5732,7 +5732,7 @@ (define_insn "rdhwr_synci_step_" [(set (match_operand:P 0 "register_operand" "=d") - (unspec_volatile [(const_int 1)] + (unspec_volatile:P [(const_int 1)] UNSPEC_RDHWR))] "ISA_HAS_SYNCI" "rdhwr\t%0,$1") diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 8f28e8e56abd..1522b0b27ccd 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -3301,7 +3301,7 @@ (define_insn "riscv_frcsr" [(set (match_operand:SI 0 "register_operand" "=r") - (unspec_volatile [(const_int 0)] UNSPECV_FRCSR))] + (unspec_volatile:SI [(const_int 0)] UNSPECV_FRCSR))] "TARGET_HARD_FLOAT || TARGET_ZFINX" "frcsr\t%0" [(set_attr "type" "fmove")]) @@ -3314,7 +3314,7 @@ (define_insn "riscv_frflags" [(set (match_operand:SI 0 "register_operand" "=r") - (unspec_volatile [(const_int 0)] UNSPECV_FRFLAGS))] + (unspec_volatile:SI [(const_int 0)] UNSPECV_FRFLAGS))] "TARGET_HARD_FLOAT || TARGET_ZFINX" "frflags\t%0" [(set_attr "type" "fmove")]) diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 4bdb679daf20..bc740a700152 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -12252,9 +12252,9 @@ (define_insn "@split_stack_call" [(set (pc) (label_ref (match_operand 2 "" ""))) ; call done label - (set (reg:P 1) (unspec_volatile [(match_operand 0 "bras_sym_operand" "X") - (reg:P 1)] - UNSPECV_SPLIT_STACK_CALL)) + (set (reg:P 1) (unspec_volatile:P [(match_operand 0 "bras_sym_operand" "X") + (reg:P 1)] + UNSPECV_SPLIT_STACK_CALL)) (use (label_ref (match_operand 1 "" "X"))) ; parm block label (use (match_operand 3 "const_int_operand" "X")) ; frame size (use (match_operand 4 "const_int_operand" "X"))] ; arg size @@ -12274,9 +12274,9 @@ (match_operand 5 "" "") ; condition (label_ref (match_operand 2 "" "")) ; call done label (pc))) - (set (reg:P 1) (unspec_volatile [(match_operand 0 "bras_sym_operand" "X") - (reg:P 1)] - UNSPECV_SPLIT_STACK_CALL)) + (set (reg:P 1) (unspec_volatile:P [(match_operand 0 "bras_sym_operand" "X") + (reg:P 1)] + UNSPECV_SPLIT_STACK_CALL)) (use (label_ref (match_operand 1 "" "X"))) ; parm block label (use (match_operand 3 "const_int_operand" "X")) ; frame size (use (match_operand 4 "const_int_operand" "X"))] ; arg size diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index 193f40d44195..8321d9fa1212 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -10936,7 +10936,7 @@ ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). (define_insn "sp_switch_1" - [(set (reg:SI SP_REG) (unspec_volatile [(match_operand:SI 0 "" "")] + [(set (reg:SI SP_REG) (unspec_volatile:SI [(match_operand:SI 0 "" "")] UNSPECV_SP_SWITCH_B))] "TARGET_SH1" { -- 2.47.2