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.

Reply via email to