[llvm] d6f1c85 - [LoongArch] Implement TargetLowering::isLegalAddressingMode() hook

via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 1 22:16:18 PST 2023


Author: gonglingqin
Date: 2023-02-02T14:01:44+08:00
New Revision: d6f1c85edb36e789307ceebcba6e096bd7f958a7

URL: https://github.com/llvm/llvm-project/commit/d6f1c85edb36e789307ceebcba6e096bd7f958a7
DIFF: https://github.com/llvm/llvm-project/commit/d6f1c85edb36e789307ceebcba6e096bd7f958a7.diff

LOG: [LoongArch] Implement TargetLowering::isLegalAddressingMode() hook

Use the exact addressing mode information instead of the default to
make better use of offsets in instructions.

Differential Revision: https://reviews.llvm.org/D142874

Added: 
    

Modified: 
    llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
    llvm/lib/Target/LoongArch/LoongArchISelLowering.h
    llvm/test/CodeGen/LoongArch/ldptr.ll
    llvm/test/CodeGen/LoongArch/stptr.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index 0eb0d188cf25..d4684a589100 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -3142,3 +3142,48 @@ bool LoongArchTargetLowering::decomposeMulByConstant(LLVMContext &Context,
 
   return false;
 }
+
+bool LoongArchTargetLowering::isLegalAddressingMode(const DataLayout &DL,
+                                                    const AddrMode &AM,
+                                                    Type *Ty, unsigned AS,
+                                                    Instruction *I) const {
+  // LoongArch has four basic addressing modes:
+  //  1. reg
+  //  2. reg + 12-bit signed offset
+  //  3. reg + 14-bit signed offset left-shifted by 2
+  //  4. reg1 + reg2
+  // TODO: Add more checks after support vector extension.
+
+  // No global is ever allowed as a base.
+  if (AM.BaseGV)
+    return false;
+
+  // Require a 12 or 14 bit signed offset.
+  if (!isInt<12>(AM.BaseOffs) || !isShiftedInt<14, 2>(AM.BaseOffs))
+    return false;
+
+  switch (AM.Scale) {
+  case 0:
+    // "i" is not allowed.
+    if (!AM.HasBaseReg)
+      return false;
+    // Otherwise we have "r+i".
+    break;
+  case 1:
+    // "r+r+i" is not allowed.
+    if (AM.HasBaseReg && AM.BaseOffs != 0)
+      return false;
+    // Otherwise we have "r+r" or "r+i".
+    break;
+  case 2:
+    // "2*r+r" or "2*r+i" is not allowed.
+    if (AM.HasBaseReg || AM.BaseOffs)
+      return false;
+    // Otherwise we have "r+r".
+    break;
+  default:
+    return false;
+  }
+
+  return true;
+}

diff  --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
index 43a30f04f194..bb4341e2a3e3 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
@@ -183,6 +183,10 @@ class LoongArchTargetLowering : public TargetLowering {
 
   bool isUsedByReturnOnly(SDNode *N, SDValue &Chain) const override;
 
+  bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty,
+                             unsigned AS,
+                             Instruction *I = nullptr) const override;
+
 private:
   /// Target-specific function used to lower LoongArch calling conventions.
   typedef bool LoongArchCCAssignFn(const DataLayout &DL, LoongArchABI::ABI ABI,

diff  --git a/llvm/test/CodeGen/LoongArch/ldptr.ll b/llvm/test/CodeGen/LoongArch/ldptr.ll
index 81254164e7e5..bab449b3c460 100644
--- a/llvm/test/CodeGen/LoongArch/ldptr.ll
+++ b/llvm/test/CodeGen/LoongArch/ldptr.ll
@@ -81,12 +81,10 @@ entry:
 define i64 @ldptr_d(ptr %p) nounwind {
 ; LA32-LABEL: ldptr_d:
 ; LA32:       # %bb.0: # %entry
-; LA32-NEXT:    ori $a1, $zero, 2052
+; LA32-NEXT:    ori $a1, $zero, 2048
 ; LA32-NEXT:    add.w $a1, $a0, $a1
-; LA32-NEXT:    ori $a2, $zero, 2048
-; LA32-NEXT:    add.w $a0, $a0, $a2
-; LA32-NEXT:    ld.w $a0, $a0, 0
-; LA32-NEXT:    ld.w $a1, $a1, 0
+; LA32-NEXT:    ld.w $a0, $a1, 0
+; LA32-NEXT:    ld.w $a1, $a1, 4
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: ldptr_d:
@@ -104,11 +102,9 @@ define i64 @ldptr_d_too_big_offset(ptr %p) nounwind {
 ; LA32-LABEL: ldptr_d_too_big_offset:
 ; LA32:       # %bb.0: # %entry
 ; LA32-NEXT:    lu12i.w $a1, 8
-; LA32-NEXT:    ori $a2, $a1, 4
-; LA32-NEXT:    add.w $a2, $a0, $a2
-; LA32-NEXT:    add.w $a0, $a0, $a1
-; LA32-NEXT:    ld.w $a0, $a0, 0
-; LA32-NEXT:    ld.w $a1, $a2, 0
+; LA32-NEXT:    add.w $a1, $a0, $a1
+; LA32-NEXT:    ld.w $a0, $a1, 0
+; LA32-NEXT:    ld.w $a1, $a1, 4
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: ldptr_d_too_big_offset:

diff  --git a/llvm/test/CodeGen/LoongArch/stptr.ll b/llvm/test/CodeGen/LoongArch/stptr.ll
index 5b6998b08731..644a931ca758 100644
--- a/llvm/test/CodeGen/LoongArch/stptr.ll
+++ b/llvm/test/CodeGen/LoongArch/stptr.ll
@@ -76,11 +76,9 @@ define void @stptr_d_too_small_offset(ptr %p, i64 %val) nounwind {
 define void @stptr_d(ptr %p, i64 %val) nounwind {
 ; LA32-LABEL: stptr_d:
 ; LA32:       # %bb.0:
-; LA32-NEXT:    ori $a3, $zero, 2052
-; LA32-NEXT:    add.w $a3, $a0, $a3
-; LA32-NEXT:    st.w $a2, $a3, 0
-; LA32-NEXT:    ori $a2, $zero, 2048
-; LA32-NEXT:    add.w $a0, $a0, $a2
+; LA32-NEXT:    ori $a3, $zero, 2048
+; LA32-NEXT:    add.w $a0, $a0, $a3
+; LA32-NEXT:    st.w $a2, $a0, 4
 ; LA32-NEXT:    st.w $a1, $a0, 0
 ; LA32-NEXT:    ret
 ;
@@ -98,11 +96,9 @@ define void @stptr_d_too_big_offset(ptr %p, i64 %val) nounwind {
 ; LA32-LABEL: stptr_d_too_big_offset:
 ; LA32:       # %bb.0:
 ; LA32-NEXT:    lu12i.w $a3, 8
-; LA32-NEXT:    add.w $a4, $a0, $a3
-; LA32-NEXT:    st.w $a1, $a4, 0
-; LA32-NEXT:    ori $a1, $a3, 4
-; LA32-NEXT:    add.w $a0, $a0, $a1
-; LA32-NEXT:    st.w $a2, $a0, 0
+; LA32-NEXT:    add.w $a0, $a0, $a3
+; LA32-NEXT:    st.w $a2, $a0, 4
+; LA32-NEXT:    st.w $a1, $a0, 0
 ; LA32-NEXT:    ret
 ;
 ; LA64-LABEL: stptr_d_too_big_offset:


        


More information about the llvm-commits mailing list