[llvm] 8494122 - [Hexagon] Add more patterns for HVX loads and stores
Krzysztof Parzyszek via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 17 19:02:04 PDT 2021
Author: Krzysztof Parzyszek
Date: 2021-03-17T21:01:52-05:00
New Revision: 849412270b80c2bd423ad4252d60df7c8aa3c691
URL: https://github.com/llvm/llvm-project/commit/849412270b80c2bd423ad4252d60df7c8aa3c691
DIFF: https://github.com/llvm/llvm-project/commit/849412270b80c2bd423ad4252d60df7c8aa3c691.diff
LOG: [Hexagon] Add more patterns for HVX loads and stores
In particular, add patterns for loads/stores to the stack
(with a frame index as address).
Added:
Modified:
llvm/lib/Target/Hexagon/HexagonPatternsHVX.td
llvm/test/CodeGen/Hexagon/vec-align.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/Hexagon/HexagonPatternsHVX.td b/llvm/lib/Target/Hexagon/HexagonPatternsHVX.td
index cd894c555adc..c2875bc8b1c0 100644
--- a/llvm/lib/Target/Hexagon/HexagonPatternsHVX.td
+++ b/llvm/lib/Target/Hexagon/HexagonPatternsHVX.td
@@ -95,21 +95,41 @@ def unalignedstore: PatFrag<(ops node:$v, node:$a), (store $v, $a), [{
// HVX loads
-multiclass HvxLd_pat<InstHexagon MI, PatFrag Load, ValueType ResType,
+multiclass HvxLdfi_pat<InstHexagon MI, PatFrag Load, ValueType ResType,
+ PatFrag ImmPred> {
+ def: Pat<(ResType (Load (add (i32 AddrFI:$fi), ImmPred:$Off))),
+ (MI AddrFI:$fi, imm:$Off)>;
+ def: Pat<(ResType (Load (IsOrAdd (i32 AddrFI:$fi), ImmPred:$Off))),
+ (MI AddrFI:$fi, imm:$Off)>;
+ def: Pat<(ResType (Load AddrFI:$fi)), (ResType (MI AddrFI:$fi, 0))>;
+}
+
+multiclass HvxLdgi_pat<InstHexagon MI, PatFrag Load, ValueType ResType,
PatFrag ImmPred> {
+ def: Pat<(ResType (Load (add I32:$Rt, ImmPred:$Off))),
+ (MI I32:$Rt, imm:$Off)>;
def: Pat<(ResType (Load I32:$Rt)),
(MI I32:$Rt, 0)>;
- def: Pat<(ResType (Load (add I32:$Rt, ImmPred:$s))),
- (MI I32:$Rt, imm:$s)>;
+}
+
+multiclass HvxLdc_pat<InstHexagon MI, PatFrag Load, ValueType ResType> {
// The HVX selection code for shuffles can generate vector constants.
// Calling "Select" on the resulting loads from CP fails without these
// patterns.
- def: Pat<(ResType (Load (HexagonCP tconstpool:$A))),
- (MI (A2_tfrsi imm:$A), 0)>;
- def: Pat<(ResType (Load (HexagonAtPcrel tconstpool:$A))),
- (MI (C4_addipc imm:$A), 0)>;
+ def: Pat<(ResType (Load (HexagonCP tconstpool:$Addr))),
+ (MI (A2_tfrsi imm:$Addr), 0)>;
+ def: Pat<(ResType (Load (HexagonAtPcrel tconstpool:$Addr))),
+ (MI (C4_addipc imm:$Addr), 0)>;
+}
+
+multiclass HvxLd_pat<InstHexagon MI, PatFrag Load, ValueType ResType,
+ PatFrag ImmPred> {
+ defm: HvxLdfi_pat<MI, Load, ResType, ImmPred>;
+ defm: HvxLdgi_pat<MI, Load, ResType, ImmPred>;
+ defm: HvxLdc_pat <MI, Load, ResType>;
}
+// Aligned loads: everything, plus loads with valignaddr node.
multiclass HvxLda_pat<InstHexagon MI, PatFrag Load, ValueType ResType,
PatFrag ImmPred> {
let AddedComplexity = 50 in {
@@ -122,41 +142,61 @@ multiclass HvxLda_pat<InstHexagon MI, PatFrag Load, ValueType ResType,
}
let Predicates = [UseHVX] in {
+ // alignedload will match a non-temporal load as well, so try non-temporal
+ // first.
defm: HvxLda_pat<V6_vL32b_nt_ai, alignednontemporalload, VecI8, IsVecOff>;
defm: HvxLda_pat<V6_vL32b_nt_ai, alignednontemporalload, VecI16, IsVecOff>;
defm: HvxLda_pat<V6_vL32b_nt_ai, alignednontemporalload, VecI32, IsVecOff>;
+ defm: HvxLda_pat<V6_vL32b_ai, alignedload, VecI8, IsVecOff>;
+ defm: HvxLda_pat<V6_vL32b_ai, alignedload, VecI16, IsVecOff>;
+ defm: HvxLda_pat<V6_vL32b_ai, alignedload, VecI32, IsVecOff>;
- defm: HvxLda_pat<V6_vL32b_ai, alignedload, VecI8, IsVecOff>;
- defm: HvxLda_pat<V6_vL32b_ai, alignedload, VecI16, IsVecOff>;
- defm: HvxLda_pat<V6_vL32b_ai, alignedload, VecI32, IsVecOff>;
-
- defm: HvxLd_pat<V6_vL32Ub_ai, unalignedload, VecI8, IsVecOff>;
- defm: HvxLd_pat<V6_vL32Ub_ai, unalignedload, VecI16, IsVecOff>;
- defm: HvxLd_pat<V6_vL32Ub_ai, unalignedload, VecI32, IsVecOff>;
+ defm: HvxLd_pat<V6_vL32Ub_ai, unalignedload, VecI8, IsVecOff>;
+ defm: HvxLd_pat<V6_vL32Ub_ai, unalignedload, VecI16, IsVecOff>;
+ defm: HvxLd_pat<V6_vL32Ub_ai, unalignedload, VecI32, IsVecOff>;
}
+
// HVX stores
-multiclass HvxSt_pat<InstHexagon MI, PatFrag Store, PatFrag ImmPred,
- PatFrag Value> {
+multiclass HvxStfi_pat<InstHexagon MI, PatFrag Store, PatFrag Value,
+ PatFrag ImmPred> {
+ def: Pat<(Store Value:$Vs, (add (i32 AddrFI:$fi), ImmPred:$Off)),
+ (MI AddrFI:$fi, imm:$Off, Value:$Vs)>;
+ def: Pat<(Store Value:$Vs, (IsOrAdd (i32 AddrFI:$fi), ImmPred:$Off)),
+ (MI AddrFI:$fi, imm:$Off, Value:$Vs)>;
+ def: Pat<(Store Value:$Vs, AddrFI:$fi),
+ (MI AddrFI:$fi, 0, Value:$Vs)>;
+}
+
+multiclass HvxStgi_pat<InstHexagon MI, PatFrag Store, PatFrag Value,
+ PatFrag ImmPred> {
+ def: Pat<(Store Value:$Vs, (add I32:$Rt, ImmPred:$Off)),
+ (MI I32:$Rt, imm:$Off, Value:$Vs)>;
+ def: Pat<(Store Value:$Vs, (IsOrAdd I32:$Rt, ImmPred:$Off)),
+ (MI I32:$Rt, imm:$Off, Value:$Vs)>;
def: Pat<(Store Value:$Vs, I32:$Rt),
(MI I32:$Rt, 0, Value:$Vs)>;
- def: Pat<(Store Value:$Vs, (add I32:$Rt, ImmPred:$s)),
- (MI I32:$Rt, imm:$s, Value:$Vs)>;
}
-let Predicates = [UseHVX] in {
- defm: HvxSt_pat<V6_vS32b_nt_ai, alignednontemporalstore, IsVecOff, HVI8>;
- defm: HvxSt_pat<V6_vS32b_nt_ai, alignednontemporalstore, IsVecOff, HVI16>;
- defm: HvxSt_pat<V6_vS32b_nt_ai, alignednontemporalstore, IsVecOff, HVI32>;
-
- defm: HvxSt_pat<V6_vS32b_ai, alignedstore, IsVecOff, HVI8>;
- defm: HvxSt_pat<V6_vS32b_ai, alignedstore, IsVecOff, HVI16>;
- defm: HvxSt_pat<V6_vS32b_ai, alignedstore, IsVecOff, HVI32>;
+multiclass HvxSt_pat<InstHexagon MI, PatFrag Store, PatFrag Value,
+ PatFrag ImmPred> {
+ defm: HvxStfi_pat<MI, Store, Value, ImmPred>;
+ defm: HvxStgi_pat<MI, Store, Value, ImmPred>;
+}
- defm: HvxSt_pat<V6_vS32Ub_ai, unalignedstore, IsVecOff, HVI8>;
- defm: HvxSt_pat<V6_vS32Ub_ai, unalignedstore, IsVecOff, HVI16>;
- defm: HvxSt_pat<V6_vS32Ub_ai, unalignedstore, IsVecOff, HVI32>;
+let Predicates = [UseHVX] in {
+ // alignedstore will match a non-temporal store as well, so try non-temporal
+ // first.
+ defm: HvxSt_pat<V6_vS32b_nt_ai, alignednontemporalstore, HVI8, IsVecOff>;
+ defm: HvxSt_pat<V6_vS32b_nt_ai, alignednontemporalstore, HVI16, IsVecOff>;
+ defm: HvxSt_pat<V6_vS32b_nt_ai, alignednontemporalstore, HVI32, IsVecOff>;
+ defm: HvxSt_pat<V6_vS32b_ai, alignedstore, HVI8, IsVecOff>;
+ defm: HvxSt_pat<V6_vS32b_ai, alignedstore, HVI16, IsVecOff>;
+ defm: HvxSt_pat<V6_vS32b_ai, alignedstore, HVI32, IsVecOff>;
+ defm: HvxSt_pat<V6_vS32Ub_ai, unalignedstore, HVI8, IsVecOff>;
+ defm: HvxSt_pat<V6_vS32Ub_ai, unalignedstore, HVI16, IsVecOff>;
+ defm: HvxSt_pat<V6_vS32Ub_ai, unalignedstore, HVI32, IsVecOff>;
}
// Bitcasts between same-size vector types are no-ops, except for the
diff --git a/llvm/test/CodeGen/Hexagon/vec-align.ll b/llvm/test/CodeGen/Hexagon/vec-align.ll
index 6d03e42e5424..8178f53f0567 100644
--- a/llvm/test/CodeGen/Hexagon/vec-align.ll
+++ b/llvm/test/CodeGen/Hexagon/vec-align.ll
@@ -2,11 +2,10 @@
; Make sure we generate stack alignment.
; CHECK: [[REG1:r[0-9]*]] = and(r29,#-64)
-; CHECK: = add([[REG1]],#128)
-; CHECK: = add([[REG1]],#64)
-; Make sure we do not generate another -64 off SP.
-; CHECK: vmem(
-; CHECK-NOT: r{{[0-9]*}} = add(r29,#-64)
+; CHECK: vmem([[REG1]]+#2) =
+; CHECK: vmem([[REG1]]+#1) =
+; CHECK: = vmem([[REG1]]+#2)
+; CHECK: = vmem([[REG1]]+#1)
target triple = "hexagon"
@@ -42,5 +41,5 @@ declare <16 x i32> @llvm.hexagon.V6.vaddw(<16 x i32>, <16 x i32>) #1
declare void @f2(...) #0
-attributes #0 = { nounwind "target-cpu"="hexagonv60" "target-features"="+hvxv60,+hvx-length64b" }
+attributes #0 = { nounwind "target-cpu"="hexagonv65" "target-features"="+hvxv65,+hvx-length64b" }
attributes #1 = { nounwind readnone }
More information about the llvm-commits
mailing list