https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116066
Bug ID: 116066 Summary: ext-dce + uncommitted LoongArch patch breaks libcpp Product: gcc Version: 15.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: xry111 at gcc dot gnu.org Target Milestone: --- Separated from PR115877 comment 14. With my LoongArch patch to remove redundant sign-extension after 32-bit shifting (not submitted yet, heavily reduced and crafted to highlight the part triggering the issue and ease debugging but the change should be legal): diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md index bc09712bce7..979d7d333d4 100644 --- a/gcc/config/loongarch/loongarch.md +++ b/gcc/config/loongarch/loongarch.md @@ -2985,7 +2985,27 @@ (define_expand "cpymemsi" ;; ;; .................... -(define_insn "<optab><mode>3" +(define_code_attr gate [(ashiftrt "0") (ashift "0") (lshiftrt "getenv (\"SHOW_THE_BUG\")")]) + +(define_expand "<optab><mode>3" + [(set (match_operand:GPR 0 "register_operand" "=r") + (any_shift:GPR (match_operand:GPR 1 "register_operand" "r") + (match_operand:SI 2 "arith_operand" "rI")))] + "" +{ + if (<gate> && TARGET_64BIT && <MODE>mode == SImode) + { + rtx t = gen_reg_rtx (DImode); + emit_insn (gen_<optab>si3_extend (t, operands[1], operands[2])); + t = gen_lowpart (SImode, t); + SUBREG_PROMOTED_VAR_P (t) = 1; + SUBREG_PROMOTED_SET (t, SRP_SIGNED); + emit_move_insn (operands[0], t); + DONE; + } +}) + +(define_insn "*<optab><mode>3" [(set (match_operand:GPR 0 "register_operand" "=r") (any_shift:GPR (match_operand:GPR 1 "register_operand" "r") (match_operand:SI 2 "arith_operand" "rI")))] @@ -3000,7 +3020,7 @@ (define_insn "<optab><mode>3" [(set_attr "type" "shift") (set_attr "mode" "<MODE>")]) -(define_insn "*<optab>si3_extend" +(define_insn "<optab>si3_extend" [(set (match_operand:DI 0 "register_operand" "=r") (sign_extend:DI (any_shift:SI (match_operand:SI 1 "register_operand" "r") stage 2 libcpp is broken and behaving stupidly: $ ../gcc/configure --enable-languages=c,c++ --with-system-zlib --disable-fixincludes ... ... $ make STAGE1_{C,CXX}FLAGS="-O2 -g" -j32 stage2-bubble ... ... $ cat > t.c << EOF #if -0 #endif EOF $ ./gcc/cc1 -E t.c ... (fine) $ rm libcpp/expr.o # rebuild this with SHOW_THE_BUG trigger $ SHOW_THE_BUG=1 make STAGE1_{C,CXX}FLAGS="-O2 -g" -j32 stage2-bubble ... ... $ ./gcc/cc1 -E t.c t.c:1:7: warning: integer overflow in preprocessor expression 1 | #if -0 | ^ It seems ext-dce is doing something wrong. Before it: (insn 109 107 114 14 (set (reg:DI 91 [ num$17 ]) (zero_extend:DI (subreg:QI (reg:SI 133) 0))) "../../gcc/libcpp/expr.cc":1968:17 discrim 6 129 {zero_extendqidi2} (expr_list:REG_DEAD (reg:SI 133) (nil))) (insn 3470 1252 1253 145 (set (reg:DI 1528) (reg:DI 294 [ num$17 ])) "../../gcc/libcpp/expr.cc":1565:33 158 {*movdi_64bit} (nil)) (insn 1257 1256 134 145 (set (reg:DI 329 [ prephitmp_444 ]) (zero_extend:DI (subreg/s/v:QI (reg:DI 1528) 0))) "../../gcc/libcpp/expr.cc":1681:22 129 {zero_extendqidi2} (expr_list:REG_DEAD (reg:DI 1528) (nil))) During ext_dce: Processing insn: 109: r91:DI=zero_extend(r133:SI#0) REG_DEAD r133:SI Trying to simplify pattern: (zero_extend:DI (subreg:QI (reg:SI 133) 0)) rescanning insn with uid = 109. Successfully transformed to: (subreg:DI (reg:SI 133) 0) So insn 109 becomes: (insn 109 107 114 14 (set (reg:DI 91 [ num$17 ]) (subreg:DI (reg:SI 133) 0)) "../../gcc/libcpp/expr.cc":1968:17 discrim 6 158 {*movdi_64bit} (expr_list:REG_DEAD (reg:SI 133) (nil))) But insn 3470 and 1257 are not changed (i.e. in 1257 the SUBREG_PROMOTED_VAR_P, printed as "/s" isn't removed). Subsequently the combine pass optimizes 1257 to: (insn 1257 1256 134 145 (set (reg:DI 329 [ prephitmp_444 ]) (reg:DI 294 [ num$17 ])) "../../gcc/libcpp/expr.cc":1681:22 158 {*movdi_64bit} (expr_list:REG_DEAD (reg:DI 294 [ num$17 ]) (nil))) and triggers the bug.