https://gcc.gnu.org/g:27d05797670bb8cd88b30b960407794e474e0be5

commit r17-404-g27d05797670bb8cd88b30b960407794e474e0be5
Author: Xi Ruoyao <[email protected]>
Date:   Wed Feb 25 23:17:10 2026 +0800

    LoongArch: eliminate redundant extension after ctz.w
    
    The ctz.w instruction writes to the entire $rd.  So due to the range of
    the CTZ result ([0, 32]), $rd is already both sign-extended and
    zero-extended from its lower half.  But in pr90838.c we can see two
    redundant sign-extension (slli.w ...,0).  Now get rid of them.
    
    The "andi" instructions in pr90393.c are really needed, because the
    source code logic should produce 0 for zero input, but the ctz.[dw]
    instructions actually produce 64/32.
    
    gcc/
    
            * config/loongarch/loongarch.md (*ctzsi2_extend): New
            define_insn.
    
    gcc/testsuite/
    
            * gcc.dg/pr90838.c: Adjust expectation for LoongArch.

Diff:
---
 gcc/config/loongarch/loongarch.md | 9 +++++++++
 gcc/testsuite/gcc.dg/pr90838.c    | 2 +-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/gcc/config/loongarch/loongarch.md 
b/gcc/config/loongarch/loongarch.md
index 77b3298078af..f8693b7f5939 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -1452,6 +1452,15 @@
   [(set_attr "type" "clz")
    (set_attr "mode" "<MODE>")])
 
+(define_insn "*ctzsi2_extend"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (any_extend:DI
+         (ctz:SI (match_operand:SI 1 "register_operand" "r"))))]
+  "TARGET_64BIT"
+  "ctz.w\t%0,%1"
+  [(set_attr "type" "clz")
+   (set_attr "mode" "SI")])
+
 ;;
 ;;  ....................
 ;;
diff --git a/gcc/testsuite/gcc.dg/pr90838.c b/gcc/testsuite/gcc.dg/pr90838.c
index 99c413e26271..fc7a045d53f6 100644
--- a/gcc/testsuite/gcc.dg/pr90838.c
+++ b/gcc/testsuite/gcc.dg/pr90838.c
@@ -87,4 +87,4 @@ int ctz4 (unsigned long x)
 /* { dg-final { scan-tree-dump-times {= \.CTZ} 4 "forwprop2" { target { 
loongarch64*-*-* } } } } */
 /* { dg-final { scan-assembler-times "ctz.d\t" 1 { target { loongarch64*-*-* } 
} } } */
 /* { dg-final { scan-assembler-times "ctz.w\t" 3 { target { loongarch64*-*-* } 
} } } */
-/* { dg-final { scan-assembler-times "\(andi|slli.w\)\t" 4 { target { 
loongarch64*-*-* } } } } */
+/* { dg-final { scan-assembler-times "andi\t" 2 { target { loongarch64*-*-* } 
} } } */

Reply via email to