https://gcc.gnu.org/g:4bcae7a19c18b2212c503c836088749e56238336

commit r17-4495-g4bcae7a19c18b2212c503c836088749e56238336
Author: Yongqiang Tian <[email protected]>
Date:   Sun Sep 20 12:18:36 2026 -0600

    [PATCH v2] ifcvt: Ignore debug insns in noce lifetime check [PR127423]
    
    A DEBUG_INSN VAR_LOCATION can mention if_info->x without representing an
    ordinary use.  Exclude debug instructions from the overlap scan so that
    debug-only payloads do not suppress min/max if-conversion.
    
    Assisted-by: OpenAI Codex 5.6 Sol, co-reviewed by Claude and Yongqiang Tian.
    
    ---
    Thanks for pointing this out.  I checked the RTL immediately after `ce2`,
    rather than relying only on what var-tracking eventually produces.
    
    For the reported case, the transformed sequence first binds `xghost` to the
    old value of `if_info->x`, then defines `if_info->x` with `smin`, and only 
then
    binds `result` to the new value.  The register is already defined at the 
first
    debug bind, and no ordinary instruction changes it before that program 
point.
    
    This ordering also follows from the interval involved here: the check scans
    `(cond_earliest, jump]`, while the merged definition is emitted at the 
former
    jump position.  Ignoring the debug instruction in this membership check does
    not move the bind across the new definition.
    
    As a secondary check, var-tracking represents `xghost` using the entry value
    when that value is recoverable.  In an additional variant where an opaque
    read-write asm operand prevents recovery of the old value, var-tracking 
makes
    `xghost` unavailable instead of associating it with the new minimum.  Based 
on
    these checks, I do not think an explicit reset is needed in
    `noce_get_alt_condition` for this transformation.
    
    I also strengthened the regression test.  `-fcompare-debug` alone can pass
    vacuously if `ce2` stops performing the conversion in both compilations.  
The
    test now compiles explicitly with `-g`, retains `-fcompare-debug`, and 
checks
    that the resulting assembly contains exactly one `min`.  The strengthened
    test produces 14 expected passes with the patched compiler.  The pristine
    compiler reports seven `-fcompare-debug failure (length)` failures, and a
    separate control with `ce2` disabled fails the assembly check.
    
    Thank you very much for your help.  Any further suggestions would be greatly
    appreciated.
    
    Changes in v2:
    
    - Compile the regression test explicitly with `-g`.
    - Retain `-fcompare-debug` to check debug/no-debug convergence.
    - Require exactly one RISC-V `min` instruction so the test cannot pass 
without
      exercising the intended if-conversion.
    
            PR rtl-optimization/127423
    
    gcc/ChangeLog:
    
            * ifcvt.cc (noce_get_alt_condition): Ignore debug instructions when
            checking whether if_info->x is mentioned in the interval.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/riscv/pr127423.c: New test.
    
    Signed-off-by: Yongqiang Tian <[email protected]>

Diff:
---
 gcc/ifcvt.cc                              |  3 ++-
 gcc/testsuite/gcc.target/riscv/pr127423.c | 18 ++++++++++++++++++
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/gcc/ifcvt.cc b/gcc/ifcvt.cc
index 7d23ce115bdb..618c2976c5d7 100644
--- a/gcc/ifcvt.cc
+++ b/gcc/ifcvt.cc
@@ -3038,7 +3038,8 @@ noce_get_alt_condition (noce_if_info *if_info, rtx target,
 
   /* X may not be mentioned in the range (cond_earliest, jump].  */
   for (insn = if_info->jump; insn != *earliest; insn = PREV_INSN (insn))
-    if (INSN_P (insn) && reg_overlap_mentioned_p (if_info->x, PATTERN (insn)))
+    if (NONDEBUG_INSN_P (insn)
+       && reg_overlap_mentioned_p (if_info->x, PATTERN (insn)))
       return NULL;
 
   /* A and B may not be modified in the range [cond_earliest, jump).  */
diff --git a/gcc/testsuite/gcc.target/riscv/pr127423.c 
b/gcc/testsuite/gcc.target/riscv/pr127423.c
new file mode 100644
index 000000000000..7c1e25bf6400
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr127423.c
@@ -0,0 +1,18 @@
+/* PR rtl-optimization/127423 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -g -fno-tree-forwprop -fdisable-tree-phiopt1 
-fdisable-tree-phiopt2 -fdisable-tree-phiopt3 -fdisable-tree-phiopt4 
-march=rv64gc_zbb -mabi=lp64d -ffunction-sections -fcompare-debug" } */
+/* { dg-final { scan-assembler-times {\mmin\t} 1 } } */
+
+#define ATTR __attribute__ ((noinline, noclone))
+
+ATTR int
+debug_payload_min (int a, int b)
+{
+  _Bool pred = a < b;
+  asm volatile ("" : : "r" (pred));
+  int result = b;
+  int xghost = a;
+  if (pred)
+    result = a;
+  return result;
+}

Reply via email to