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.
---
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(+)
create mode 100644 gcc/testsuite/gcc.target/loongarch/mem-and-mask-opt.c
diff --git a/gcc/config/loongarch/loongarch.md
b/gcc/config/loongarch/loongarch.md
index 625f30ca265..d5c01b99ae9 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 34cf74d5d66..8460618b501 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 00000000000..9b3a5cdbbac
--- /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;
+}
--
2.38.1