https://gcc.gnu.org/g:796aa9e3977bb3ba44b3f188f8de45b7b028f999

commit r16-4953-g796aa9e3977bb3ba44b3f188f8de45b7b028f999
Author: Guo Jie <[email protected]>
Date:   Sun Nov 2 11:32:07 2025 +0800

    LoongArch: Make full use of load insns with unsigned extension
    
    gcc/ChangeLog:
    
            * config/loongarch/loongarch.md
            (and_load_zero_extend<mode>): New combiner.
            * config/loongarch/predicates.md
            (mask_operand): New predicate.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/loongarch/mem-and-mask-opt.c: New test.

Diff:
---
 gcc/config/loongarch/loongarch.md                  | 15 ++++++++++++++
 gcc/config/loongarch/predicates.md                 |  5 +++++
 .../gcc.target/loongarch/mem-and-mask-opt.c        | 23 ++++++++++++++++++++++
 3 files changed, 43 insertions(+)

diff --git a/gcc/config/loongarch/loongarch.md 
b/gcc/config/loongarch/loongarch.md
index 9371134a69db..c61abcea3eda 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -1636,6 +1636,21 @@
     operands[3] = tmp;
   })
 
+(define_insn "and_load_zero_extend<mode>"
+  [(set (match_operand:X 0 "register_operand" "=r,r,r,r,r,r")
+       (and:X (match_operand:X 1 "memory_operand" "%m,m,m,k,k,k")
+              (match_operand:X 2 "mask_operand" "Yb,Yh,Yw,Yb,Yh,Yw")))]
+  ""
+  "@
+   ld.bu\t%0,%1
+   ld.hu\t%0,%1
+   ld.wu\t%0,%1
+   ldx.bu\t%0,%1
+   ldx.hu\t%0,%1
+   ldx.wu\t%0,%1"
+  [(set_attr "move_type" "load,load,load,load,load,load")
+   (set_attr "mode" "<MODE>")])
+
 ;; We always avoid the shift operation in bstrins_<mode>_for_ior_mask
 ;; if possible, but the result may be sub-optimal when one of the masks
 ;; is (1 << N) - 1 and one of the src register is the dest register.
diff --git a/gcc/config/loongarch/predicates.md 
b/gcc/config/loongarch/predicates.md
index 34cf74d5d66e..8460618b501b 100644
--- a/gcc/config/loongarch/predicates.md
+++ b/gcc/config/loongarch/predicates.md
@@ -413,6 +413,11 @@
        (match_operand 0 "low_bitmask_operand")
        (match_operand 0 "ins_zero_bitmask_operand")))
 
+(define_predicate "mask_operand"
+  (ior (match_operand 0 "qi_mask_operand")
+       (match_operand 0 "hi_mask_operand")
+       (match_operand 0 "si_mask_operand")))
+
 (define_predicate "const_call_insn_operand"
   (match_code "const,symbol_ref,label_ref")
 {
diff --git a/gcc/testsuite/gcc.target/loongarch/mem-and-mask-opt.c 
b/gcc/testsuite/gcc.target/loongarch/mem-and-mask-opt.c
new file mode 100644
index 000000000000..9b3a5cdbbac6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/mem-and-mask-opt.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+/* { dg-final { scan-assembler-not "bstrpick" } } */
+/* { dg-final { scan-assembler "ld\\.wu" } } */
+
+struct st
+{
+  char const *name;
+};
+struct fst
+{
+  struct st *groups;
+};
+
+struct fst *pfunc (int);
+
+const char *
+test (int pc, unsigned group)
+{
+  struct fst *pci = pfunc (pc);
+
+  return pci->groups[group].name;
+}

Reply via email to