[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