[LLVM][CodeGen][SVE] Make use of predicate load/store "mul vl" addressing mode. (#206997)
This commit is contained in:
1 parent
179badc020
commit
0470117106
6 files changed
+238
-100
No files matched your search
@@ -402,7 +402,6 @@ public:
|
||||
void SelectMultiVectorMoveZ(SDNode *N, unsigned NumVecs,
|
||||
unsigned Op, unsigned MaxIdx, unsigned Scale,
|
||||
unsigned BaseReg = 0);
|
||||
bool SelectAddrModeFrameIndexSVE(SDValue N, SDValue &Base, SDValue &OffImm);
|
||||
/// SVE Reg+Imm addressing mode.
|
||||
template <int64_t Min, int64_t Max>
|
||||
bool SelectAddrModeIndexedSVE(SDNode *Root, SDValue N, SDValue &Base,
|
||||
@@ -2534,23 +2533,6 @@ void AArch64DAGToDAGISel::SelectPredicatedStore(SDNode *N, unsigned NumVecs,
|
||||
ReplaceNode(N, St);
|
||||
}
|
||||
|
||||
bool AArch64DAGToDAGISel::SelectAddrModeFrameIndexSVE(SDValue N, SDValue &Base,
|
||||
SDValue &OffImm) {
|
||||
SDLoc dl(N);
|
||||
const DataLayout &DL = CurDAG->getDataLayout();
|
||||
const TargetLowering *TLI = getTargetLowering();
|
||||
|
||||
// Try to match it for the frame address
|
||||
if (auto FINode = dyn_cast<FrameIndexSDNode>(N)) {
|
||||
int FI = FINode->getIndex();
|
||||
Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy(DL));
|
||||
OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void AArch64DAGToDAGISel::SelectPostStore(SDNode *N, unsigned NumVecs,
|
||||
unsigned Opc) {
|
||||
SDLoc dl(N);
|
||||
|
||||
@@ -612,8 +612,6 @@ def simm7s16 : Operand<i32> {
|
||||
let OperandType = "OPERAND_IMMEDIATE";
|
||||
}
|
||||
|
||||
def am_sve_fi : ComplexPattern<iPTR, 2, "SelectAddrModeFrameIndexSVE", []>;
|
||||
|
||||
def am_indexed7s8 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S8", []>;
|
||||
def am_indexed7s16 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S16", []>;
|
||||
def am_indexed7s32 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S32", []>;
|
||||
|
||||
@@ -3339,26 +3339,6 @@ let Predicates = [HasSVE_or_SME] in {
|
||||
(STR_ZXI ZPR:$val, GPR64sp:$base, (i64 0))>;
|
||||
}
|
||||
|
||||
multiclass unpred_store_predicate<ValueType Ty, Instruction Store> {
|
||||
def _fi : Pat<(store (Ty PPR:$val), (am_sve_fi GPR64sp:$base, simm9:$offset)),
|
||||
(Store PPR:$val, GPR64sp:$base, simm9:$offset)>;
|
||||
|
||||
def _default : Pat<(store (Ty PPR:$Val), GPR64:$base),
|
||||
(Store PPR:$Val, GPR64:$base, (i64 0))>;
|
||||
}
|
||||
|
||||
defm Pat_Store_P16 : unpred_store_predicate<nxv16i1, STR_PXI>;
|
||||
|
||||
multiclass unpred_load_predicate<ValueType Ty, Instruction Load> {
|
||||
def _fi : Pat<(Ty (load (am_sve_fi GPR64sp:$base, simm9:$offset))),
|
||||
(Load GPR64sp:$base, simm9:$offset)>;
|
||||
|
||||
def _default : Pat<(Ty (load GPR64:$base)),
|
||||
(Load GPR64:$base, (i64 0))>;
|
||||
}
|
||||
|
||||
defm Pat_Load_P16 : unpred_load_predicate<nxv16i1, LDR_PXI>;
|
||||
|
||||
multiclass ld1<Instruction RegRegInst, Instruction RegImmInst, ValueType Ty,
|
||||
SDPatternOperator Load, ValueType PredTy, ValueType MemVT, ComplexPattern AddrCP> {
|
||||
// reg + reg
|
||||
|
||||
@@ -376,6 +376,18 @@ def SVEShiftImmR64 : ComplexPattern<i64, 1, "SelectSVEShiftImm<1, 64, true>", []
|
||||
|
||||
def SVEShiftSplatImmR : ComplexPattern<iAny, 1, "SelectSVEShiftSplatImmR", []>;
|
||||
|
||||
let WantsRoot = true in {
|
||||
def am_sve_indexed_s4 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedSVE<-8, 7>">;
|
||||
def am_sve_indexed_s6 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedSVE<-32, 31>">;
|
||||
def am_sve_indexed_s9 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedSVE<-256, 255>">;
|
||||
}
|
||||
|
||||
def am_sve_regreg_lsl0 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<0>", []>;
|
||||
def am_sve_regreg_lsl1 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<1>", []>;
|
||||
def am_sve_regreg_lsl2 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<2>", []>;
|
||||
def am_sve_regreg_lsl3 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<3>", []>;
|
||||
def am_sve_regreg_lsl4 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<4>", []>;
|
||||
|
||||
def SVEAllActive : ComplexPattern<untyped, 0, "SelectAllActivePredicate", []>;
|
||||
def SVEAnyPredicate : ComplexPattern<untyped, 0, "SelectAnyPredicate", []>;
|
||||
|
||||
@@ -7379,6 +7391,14 @@ multiclass sve_mem_p_spill<string asm> {
|
||||
|
||||
def : InstAlias<asm # "\t$Pt, [$Rn]",
|
||||
(!cast<Instruction>(NAME) PPRorPNRAny:$Pt, GPR64sp:$Rn, 0), 1>;
|
||||
|
||||
// base + immediate (mul vl)
|
||||
def : Pat<(store nxv16i1:$val, (am_sve_indexed_s9 GPR64sp:$base, simm9:$offset)),
|
||||
(!cast<Instruction>(NAME) PPR:$val, GPR64sp:$base, simm9:$offset)>;
|
||||
|
||||
// base
|
||||
def : Pat<(store nxv16i1:$val, GPR64:$base),
|
||||
(!cast<Instruction>(NAME) PPR:$val, GPR64:$base, (i64 0))>;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@@ -8702,6 +8722,14 @@ multiclass sve_mem_p_fill<string asm> {
|
||||
|
||||
def : InstAlias<asm # "\t$Pt, [$Rn]",
|
||||
(!cast<Instruction>(NAME) PPRorPNRAny:$Pt, GPR64sp:$Rn, 0), 1>;
|
||||
|
||||
// base + immediate (mul vl)
|
||||
def : Pat<(nxv16i1 (load (am_sve_indexed_s9 GPR64sp:$base, simm9:$offset))),
|
||||
(!cast<Instruction>(NAME) GPR64sp:$base, simm9:$offset)>;
|
||||
|
||||
// base
|
||||
def : Pat<(nxv16i1 (load GPR64:$base)),
|
||||
(!cast<Instruction>(NAME) GPR64:$base, (i64 0))>;
|
||||
}
|
||||
|
||||
class sve2_mem_gldnt_vs_base<bits<5> opc, dag iops, string asm,
|
||||
@@ -9903,19 +9931,6 @@ multiclass sve_int_perm_bin_perm_128_zz<bits<2> opc, bit P, string asm, SDPatter
|
||||
def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME)>;
|
||||
}
|
||||
|
||||
/// Addressing modes
|
||||
let WantsRoot = true in {
|
||||
def am_sve_indexed_s4 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedSVE<-8, 7>">;
|
||||
def am_sve_indexed_s6 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedSVE<-32, 31>">;
|
||||
def am_sve_indexed_s9 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedSVE<-256, 255>">;
|
||||
}
|
||||
|
||||
def am_sve_regreg_lsl0 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<0>", []>;
|
||||
def am_sve_regreg_lsl1 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<1>", []>;
|
||||
def am_sve_regreg_lsl2 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<2>", []>;
|
||||
def am_sve_regreg_lsl3 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<3>", []>;
|
||||
def am_sve_regreg_lsl4 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<4>", []>;
|
||||
|
||||
// Predicated pseudo floating point two operand instructions.
|
||||
multiclass sve_fp_bin_pred_hfd<SDPatternOperator op> {
|
||||
def _H_UNDEF : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
|
||||
|
||||
@@ -111,16 +111,10 @@ define aarch64_sve_vector_pcs <vscale x 16 x i1> @caller_with_svepred_arg_1xv16i
|
||||
define aarch64_sve_vector_pcs [4 x <vscale x 16 x i1>] @callee_with_svepred_arg_4xv16i1_4xv16i1([4 x <vscale x 16 x i1>] %arg1, [4 x <vscale x 16 x i1>] %arg2) {
|
||||
; CHECK: name: callee_with_svepred_arg_4xv16i1_4xv16i1
|
||||
; CHECK: [[BASE:%[0-9]+]]:gpr64common = COPY $x0
|
||||
; CHECK: [[OFFSET1:%[0-9]+]]:gpr64 = CNTD_XPiI 31, 1, implicit $vg
|
||||
; CHECK: [[ADDR1:%[0-9]+]]:gpr64common = nuw ADDXrr [[BASE]], killed [[OFFSET1]]
|
||||
; CHECK: [[PRED1:%[0-9]+]]:ppr = LDR_PXI killed [[ADDR1]], 0 :: (load (<vscale x 1 x s16>))
|
||||
; CHECK: [[OFFSET2:%[0-9]+]]:gpr64 = CNTW_XPiI 31, 1, implicit $vg
|
||||
; CHECK: [[ADDR2:%[0-9]+]]:gpr64common = ADDXrr [[BASE]], killed [[OFFSET2]]
|
||||
; CHECK: [[PRED2:%[0-9]+]]:ppr = LDR_PXI killed [[ADDR2]], 0 :: (load (<vscale x 1 x s16>))
|
||||
; CHECK: [[OFFSET3:%[0-9]+]]:gpr64 = CNTD_XPiI 31, 3, implicit $vg
|
||||
; CHECK: [[ADDR3:%[0-9]+]]:gpr64common = ADDXrr [[BASE]], killed [[OFFSET3]]
|
||||
; CHECK: [[PRED3:%[0-9]+]]:ppr = LDR_PXI killed [[ADDR3]], 0 :: (load (<vscale x 1 x s16>))
|
||||
; CHECK: [[PRED0:%[0-9]+]]:ppr = LDR_PXI [[BASE]], 0 :: (load (<vscale x 1 x s16>))
|
||||
; CHECK: [[PRED1:%[0-9]+]]:ppr = LDR_PXI [[BASE]], 1 :: (load (<vscale x 1 x s16>))
|
||||
; CHECK: [[PRED2:%[0-9]+]]:ppr = LDR_PXI [[BASE]], 2 :: (load (<vscale x 1 x s16>))
|
||||
; CHECK: [[PRED3:%[0-9]+]]:ppr = LDR_PXI [[BASE]], 3 :: (load (<vscale x 1 x s16>))
|
||||
; CHECK: $p0 = COPY [[PRED0]]
|
||||
; CHECK: $p1 = COPY [[PRED1]]
|
||||
; CHECK: $p2 = COPY [[PRED2]]
|
||||
@@ -144,18 +138,12 @@ define [4 x <vscale x 16 x i1>] @caller_with_svepred_arg_4xv16i1_4xv16i1([4 x <v
|
||||
; CHECK: [[PRED2:%[0-9]+]]:ppr = COPY $p2
|
||||
; CHECK: [[PRED1:%[0-9]+]]:ppr = COPY $p1
|
||||
; CHECK: [[PRED0:%[0-9]+]]:ppr = COPY $p0
|
||||
; CHECK: [[OFFSET1:%[0-9]+]]:gpr64 = CNTD_XPiI 31, 1, implicit $vg
|
||||
; CHECK: [[OFFSET2:%[0-9]+]]:gpr64 = CNTW_XPiI 31, 1, implicit $vg
|
||||
; CHECK: [[OFFSET3:%[0-9]+]]:gpr64 = CNTD_XPiI 31, 3, implicit $vg
|
||||
; CHECK: [[STACK:%[0-9]+]]:gpr64common = ADDXri %stack.0, 0, 0
|
||||
; CHECK: [[ADDR3:%[0-9]+]]:gpr64common = ADDXrr [[STACK]], [[OFFSET3]]
|
||||
; CHECK: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
|
||||
; CHECK: STR_PXI [[PRED3]], killed [[ADDR3]], 0 :: (store (<vscale x 1 x s16>))
|
||||
; CHECK: [[ADDR2:%[0-9]+]]:gpr64common = ADDXrr [[STACK]], [[OFFSET2]]
|
||||
; CHECK: STR_PXI [[PRED2]], killed [[ADDR2]], 0 :: (store (<vscale x 1 x s16>))
|
||||
; CHECK: [[ADDR1:%[0-9]+]]:gpr64common = nuw ADDXrr [[STACK]], [[OFFSET1]]
|
||||
; CHECK: STR_PXI [[PRED1]], killed [[ADDR1]], 0 :: (store (<vscale x 1 x s16>))
|
||||
; CHECK: STR_PXI [[PRED3]], %stack.0, 3 :: (store (<vscale x 1 x s16>))
|
||||
; CHECK: STR_PXI [[PRED2]], %stack.0, 2 :: (store (<vscale x 1 x s16>))
|
||||
; CHECK: STR_PXI [[PRED1]], %stack.0, 1 :: (store (<vscale x 1 x s16>))
|
||||
; CHECK: STR_PXI [[PRED0]], %stack.0, 0 :: (store (<vscale x 1 x s16>) into %stack.0)
|
||||
; CHECK: [[STACK:%[0-9]+]]:gpr64sp = ADDXri %stack.0, 0, 0
|
||||
; CHECK: $x0 = COPY [[STACK]]
|
||||
; LINUX: BL @callee_with_svepred_arg_4xv16i1_4xv16i1, csr_aarch64_sve_aapcs, implicit-def dead $lr, implicit $sp, implicit $p0, implicit $p1, implicit $p2, implicit $p3, implicit $x0, implicit-def $sp, implicit-def $p0, implicit-def $p1, implicit-def $p2, implicit-def $p3
|
||||
; DARWIN: BL @callee_with_svepred_arg_4xv16i1_4xv16i1, csr_darwin_aarch64_sve_aapcs, implicit-def dead $lr, implicit $sp, implicit $p0, implicit $p1, implicit $p2, implicit $p3, implicit $x0, implicit-def $sp, implicit-def $p0, implicit-def $p1, implicit-def $p2, implicit-def $p3
|
||||
@@ -172,16 +160,10 @@ define [4 x <vscale x 16 x i1>] @caller_with_svepred_arg_4xv16i1_4xv16i1([4 x <v
|
||||
define aarch64_sve_vector_pcs [2 x <vscale x 32 x i1>] @callee_with_svepred_arg_1xv16i1_2xv32i1([1 x <vscale x 16 x i1>] %arg1, [2 x <vscale x 32 x i1>] %arg2) {
|
||||
; CHECK: name: callee_with_svepred_arg_1xv16i1_2xv32i1
|
||||
; CHECK: [[BASE:%[0-9]+]]:gpr64common = COPY $x0
|
||||
; CHECK: [[OFFSET1:%[0-9]+]]:gpr64 = CNTD_XPiI 31, 1, implicit $vg
|
||||
; CHECK: [[ADDR1:%[0-9]+]]:gpr64common = nuw ADDXrr [[BASE]], killed [[OFFSET1]]
|
||||
; CHECK: [[PRED1:%[0-9]+]]:ppr = LDR_PXI killed [[ADDR1]], 0 :: (load (<vscale x 1 x s16>))
|
||||
; CHECK: [[OFFSET2:%[0-9]+]]:gpr64 = CNTW_XPiI 31, 1, implicit $vg
|
||||
; CHECK: [[ADDR2:%[0-9]+]]:gpr64common = ADDXrr [[BASE]], killed [[OFFSET2]]
|
||||
; CHECK: [[PRED2:%[0-9]+]]:ppr = LDR_PXI killed [[ADDR2]], 0 :: (load (<vscale x 1 x s16>))
|
||||
; CHECK: [[OFFSET3:%[0-9]+]]:gpr64 = CNTD_XPiI 31, 3, implicit $vg
|
||||
; CHECK: [[ADDR3:%[0-9]+]]:gpr64common = ADDXrr [[BASE]], killed [[OFFSET3]]
|
||||
; CHECK: [[PRED3:%[0-9]+]]:ppr = LDR_PXI killed [[ADDR3]], 0 :: (load (<vscale x 1 x s16>))
|
||||
; CHECK: [[PRED0:%[0-9]+]]:ppr = LDR_PXI [[BASE]], 0 :: (load (<vscale x 1 x s16>))
|
||||
; CHECK: [[PRED1:%[0-9]+]]:ppr = LDR_PXI [[BASE]], 1 :: (load (<vscale x 1 x s16>))
|
||||
; CHECK: [[PRED2:%[0-9]+]]:ppr = LDR_PXI [[BASE]], 2 :: (load (<vscale x 1 x s16>))
|
||||
; CHECK: [[PRED3:%[0-9]+]]:ppr = LDR_PXI [[BASE]], 3 :: (load (<vscale x 1 x s16>))
|
||||
; CHECK: $p0 = COPY [[PRED0]]
|
||||
; CHECK: $p1 = COPY [[PRED1]]
|
||||
; CHECK: $p2 = COPY [[PRED2]]
|
||||
@@ -205,18 +187,12 @@ define [2 x <vscale x 32 x i1>] @caller_with_svepred_arg_2xv32i1_1xv16i1([2 x <v
|
||||
; CHECK: [[PRED2:%[0-9]+]]:ppr = COPY $p2
|
||||
; CHECK: [[PRED1:%[0-9]+]]:ppr = COPY $p1
|
||||
; CHECK: [[PRED0:%[0-9]+]]:ppr = COPY $p0
|
||||
; CHECK: [[OFFSET3:%[0-9]+]]:gpr64 = CNTD_XPiI 31, 3, implicit $vg
|
||||
; CHECK: [[STACK:%[0-9]+]]:gpr64common = ADDXri %stack.0, 0, 0
|
||||
; CHECK: [[ADDR3:%[0-9]+]]:gpr64common = ADDXrr [[STACK]], killed [[OFFSET3]]
|
||||
; CHECK: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp
|
||||
; CHECK: STR_PXI [[PRED3]], killed [[ADDR3]], 0 :: (store (<vscale x 1 x s16>))
|
||||
; CHECK: [[OFFSET2:%[0-9]+]]:gpr64 = CNTW_XPiI 31, 1, implicit $vg
|
||||
; CHECK: [[ADDR2:%[0-9]+]]:gpr64common = ADDXrr [[STACK]], killed [[OFFSET2]]
|
||||
; CHECK: STR_PXI [[PRED2]], killed [[ADDR2]], 0 :: (store (<vscale x 1 x s16>))
|
||||
; CHECK: [[OFFSET1:%[0-9]+]]:gpr64 = CNTD_XPiI 31, 1, implicit $vg
|
||||
; CHECK: [[ADDR1:%[0-9]+]]:gpr64common = nuw ADDXrr [[STACK]], killed [[OFFSET1]]
|
||||
; CHECK: STR_PXI [[PRED1]], killed [[ADDR1]], 0 :: (store (<vscale x 1 x s16>))
|
||||
; CHECK: STR_PXI [[PRED3]], %stack.0, 3 :: (store (<vscale x 1 x s16>))
|
||||
; CHECK: STR_PXI [[PRED2]], %stack.0, 2 :: (store (<vscale x 1 x s16>))
|
||||
; CHECK: STR_PXI [[PRED1]], %stack.0, 1 :: (store (<vscale x 1 x s16>))
|
||||
; CHECK: STR_PXI [[PRED0]], %stack.0, 0 :: (store (<vscale x 1 x s16>) into %stack.0)
|
||||
; CHECK: [[STACK:%[0-9]+]]:gpr64sp = ADDXri %stack.0, 0, 0
|
||||
; CHECK: $x0 = COPY [[STACK]]
|
||||
; LINUX: BL @callee_with_svepred_arg_1xv16i1_2xv32i1, csr_aarch64_sve_aapcs, implicit-def dead $lr, implicit $sp, implicit $p0, implicit $x0, implicit-def $sp, implicit-def $p0, implicit-def $p1, implicit-def $p2, implicit-def $p3
|
||||
; DARWIN: BL @callee_with_svepred_arg_1xv16i1_2xv32i1, csr_darwin_aarch64_sve_aapcs, implicit-def dead $lr, implicit $sp, implicit $p0, implicit $x0, implicit-def $sp, implicit-def $p0, implicit-def $p1, implicit-def $p2, implicit-def $p3
|
||||
@@ -233,15 +209,9 @@ define aarch64_sve_vector_pcs [4 x <vscale x 16 x i1>] @callee_with_svepred_arg_
|
||||
; CHECK: [[X0:%[0-9]+]]:gpr64common = COPY $x0
|
||||
; CHECK: [[P1:%[0-9]+]]:ppr = COPY $p1
|
||||
; CHECK: [[P0:%[0-9]+]]:ppr = COPY $p0
|
||||
; CHECK: [[OFFSET3:%[0-9]+]]:gpr64 = CNTD_XPiI 31, 3, implicit $vg
|
||||
; CHECK: [[ADDR3:%[0-9]+]]:gpr64common = ADDXrr [[X0]], killed [[OFFSET3]]
|
||||
; CHECK: [[P7:%[0-9]+]]:ppr = LDR_PXI killed [[ADDR3]], 0 :: (load (<vscale x 1 x s16>))
|
||||
; CHECK: [[OFFSET2:%[0-9]+]]:gpr64 = CNTW_XPiI 31, 1, implicit $vg
|
||||
; CHECK: [[ADDR2:%[0-9]+]]:gpr64common = ADDXrr [[X0]], killed [[OFFSET2]]
|
||||
; CHECK: [[P6:%[0-9]+]]:ppr = LDR_PXI killed [[ADDR2]], 0 :: (load (<vscale x 1 x s16>))
|
||||
; CHECK: [[OFFSET1:%[0-9]+]]:gpr64 = CNTD_XPiI 31, 1, implicit $vg
|
||||
; CHECK: [[ADDR1:%[0-9]+]]:gpr64common = nuw ADDXrr [[X0]], killed [[OFFSET1]]
|
||||
; CHECK: [[P5:%[0-9]+]]:ppr = LDR_PXI killed [[ADDR1]], 0 :: (load (<vscale x 1 x s16>))
|
||||
; CHECK: [[P7:%[0-9]+]]:ppr = LDR_PXI [[X0]], 3 :: (load (<vscale x 1 x s16>))
|
||||
; CHECK: [[P6:%[0-9]+]]:ppr = LDR_PXI [[X0]], 2 :: (load (<vscale x 1 x s16>))
|
||||
; CHECK: [[P5:%[0-9]+]]:ppr = LDR_PXI [[X0]], 1 :: (load (<vscale x 1 x s16>))
|
||||
; CHECK: [[P4:%[0-9]+]]:ppr = LDR_PXI [[X0]], 0 :: (load (<vscale x 1 x s16>))
|
||||
; CHECK: [[RES0:%[0-9]+]]:ppr = AND_PPzPP [[P0]], [[P0]], killed [[P4]]
|
||||
; CHECK: [[RES1:%[0-9]+]]:ppr = AND_PPzPP [[P1]], [[P1]], killed [[P5]]
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
|
||||
; RUN: llc -mattr=+sve < %s | FileCheck %s
|
||||
; RUN: llc -mattr=+sme -force-streaming < %s | FileCheck %s
|
||||
|
||||
target triple = "aarch64-unknown-linux-gnu"
|
||||
|
||||
define <vscale x 16 x i1> @load_no_offset(ptr %base) {
|
||||
; CHECK-LABEL: load_no_offset:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: ldr p0, [x0]
|
||||
; CHECK-NEXT: ret
|
||||
%val = load <vscale x 16 x i1>, ptr %base, align 2
|
||||
ret <vscale x 16 x i1> %val
|
||||
}
|
||||
|
||||
define void @store_no_offset(ptr %base, <vscale x 16 x i1> %val) {
|
||||
; CHECK-LABEL: store_no_offset:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: str p0, [x0]
|
||||
; CHECK-NEXT: ret
|
||||
store <vscale x 16 x i1> %val, ptr %base, align 2
|
||||
ret void
|
||||
}
|
||||
|
||||
define <vscale x 16 x i1> @load_offset(ptr %base) {
|
||||
; CHECK-LABEL: load_offset:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: ldr p0, [x0, #7, mul vl]
|
||||
; CHECK-NEXT: ret
|
||||
%addr = getelementptr <vscale x 16 x i1>, ptr %base, i64 7
|
||||
%val = load <vscale x 16 x i1>, ptr %addr, align 2
|
||||
ret <vscale x 16 x i1> %val
|
||||
}
|
||||
|
||||
define void @store_offset(ptr %base, <vscale x 16 x i1> %val) {
|
||||
; CHECK-LABEL: store_offset:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: str p0, [x0, #-7, mul vl]
|
||||
; CHECK-NEXT: ret
|
||||
%addr = getelementptr <vscale x 16 x i1>, ptr %base, i64 -7
|
||||
store <vscale x 16 x i1> %val, ptr %addr, align 2
|
||||
ret void
|
||||
}
|
||||
|
||||
define <vscale x 16 x i1> @load_offset_min(ptr %base) {
|
||||
; CHECK-LABEL: load_offset_min:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: ldr p0, [x0, #-256, mul vl]
|
||||
; CHECK-NEXT: ret
|
||||
%addr = getelementptr <vscale x 16 x i1>, ptr %base, i64 -256
|
||||
%val = load <vscale x 16 x i1>, ptr %addr, align 2
|
||||
ret <vscale x 16 x i1> %val
|
||||
}
|
||||
|
||||
define void @store_offset_max(ptr %base, <vscale x 16 x i1> %val) {
|
||||
; CHECK-LABEL: store_offset_max:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: str p0, [x0, #255, mul vl]
|
||||
; CHECK-NEXT: ret
|
||||
%addr = getelementptr <vscale x 16 x i1>, ptr %base, i64 255
|
||||
store <vscale x 16 x i1> %val, ptr %addr, align 2
|
||||
ret void
|
||||
}
|
||||
|
||||
define <vscale x 16 x i1> @load_offset_too_low(ptr %base) {
|
||||
; CHECK-LABEL: load_offset_too_low:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: rdvl x8, #1
|
||||
; CHECK-NEXT: mov x9, #-514 // =0xfffffffffffffdfe
|
||||
; CHECK-NEXT: lsr x8, x8, #4
|
||||
; CHECK-NEXT: madd x8, x8, x9, x0
|
||||
; CHECK-NEXT: ldr p0, [x8]
|
||||
; CHECK-NEXT: ret
|
||||
%addr = getelementptr <vscale x 16 x i1>, ptr %base, i64 -257
|
||||
%val = load <vscale x 16 x i1>, ptr %addr, align 2
|
||||
ret <vscale x 16 x i1> %val
|
||||
}
|
||||
|
||||
define void @store_offset_too_high(ptr %base, <vscale x 16 x i1> %val) {
|
||||
; CHECK-LABEL: store_offset_too_high:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: rdvl x8, #1
|
||||
; CHECK-NEXT: mov w9, #512 // =0x200
|
||||
; CHECK-NEXT: lsr x8, x8, #4
|
||||
; CHECK-NEXT: madd x8, x8, x9, x0
|
||||
; CHECK-NEXT: str p0, [x8]
|
||||
; CHECK-NEXT: ret
|
||||
%addr = getelementptr <vscale x 16 x i1>, ptr %base, i64 256
|
||||
store <vscale x 16 x i1> %val, ptr %addr, align 2
|
||||
ret void
|
||||
}
|
||||
|
||||
define <vscale x 16 x i1> @load_fixed_offset_unknown_vscale(ptr %base) {
|
||||
; CHECK-LABEL: load_fixed_offset_unknown_vscale:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: add x8, x0, #2
|
||||
; CHECK-NEXT: ldr p0, [x8]
|
||||
; CHECK-NEXT: ret
|
||||
%addr = getelementptr i8, ptr %base, i64 2
|
||||
%val = load <vscale x 16 x i1>, ptr %addr, align 2
|
||||
ret <vscale x 16 x i1> %val
|
||||
}
|
||||
|
||||
define void @store_fixed_offset_unknown_vscale(ptr %base, <vscale x 16 x i1> %val) {
|
||||
; CHECK-LABEL: store_fixed_offset_unknown_vscale:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: add x8, x0, #2
|
||||
; CHECK-NEXT: str p0, [x8]
|
||||
; CHECK-NEXT: ret
|
||||
%addr = getelementptr i8, ptr %base, i64 2
|
||||
store <vscale x 16 x i1> %val, ptr %addr, align 2
|
||||
ret void
|
||||
}
|
||||
|
||||
; 1 * sizeof(<vscale x 16 x i1>) == 2
|
||||
define <vscale x 16 x i1> @load_fixed_offset_vscale_one(ptr %base) vscale_range(1,1) {
|
||||
; CHECK-LABEL: load_fixed_offset_vscale_one:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: ldr p0, [x0, #1, mul vl]
|
||||
; CHECK-NEXT: ret
|
||||
%addr = getelementptr i8, ptr %base, i64 2
|
||||
%val = load <vscale x 16 x i1>, ptr %addr, align 2
|
||||
ret <vscale x 16 x i1> %val
|
||||
}
|
||||
|
||||
; -2 * sizeof(<vscale x 16 x i1>) == -8
|
||||
define void @store_fixed_offset_vscale_two(ptr %base, <vscale x 16 x i1> %val) vscale_range(2,2) {
|
||||
; CHECK-LABEL: store_fixed_offset_vscale_two:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: str p0, [x0, #-2, mul vl]
|
||||
; CHECK-NEXT: ret
|
||||
%addr = getelementptr i8, ptr %base, i64 -8
|
||||
store <vscale x 16 x i1> %val, ptr %addr, align 2
|
||||
ret void
|
||||
}
|
||||
|
||||
; 255 * sizeof(<vscale x 16 x i1>) == -1020
|
||||
define <vscale x 16 x i1> @load_fixed_offset_max_vscale_two(ptr %base) vscale_range(2,2) {
|
||||
; CHECK-LABEL: load_fixed_offset_max_vscale_two:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: ldr p0, [x0, #255, mul vl]
|
||||
; CHECK-NEXT: ret
|
||||
%addr = getelementptr i8, ptr %base, i64 1020
|
||||
%val = load <vscale x 16 x i1>, ptr %addr, align 2
|
||||
ret <vscale x 16 x i1> %val
|
||||
}
|
||||
|
||||
; -256 * sizeof(<vscale x 16 x i1>) == -512
|
||||
define void @store_fixed_offset_min_vscale_one(ptr %base, <vscale x 16 x i1> %val) vscale_range(1,1) {
|
||||
; CHECK-LABEL: store_fixed_offset_min_vscale_one:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: str p0, [x0, #-256, mul vl]
|
||||
; CHECK-NEXT: ret
|
||||
%addr = getelementptr i8, ptr %base, i64 -512
|
||||
store <vscale x 16 x i1> %val, ptr %addr, align 2
|
||||
ret void
|
||||
}
|
||||
|
||||
; Offsets must be a multiple of sizeof(<vscale x 16 x i1>)
|
||||
define void @store_fixed_no_divisible_offset_vscale_one(ptr %base, <vscale x 16 x i1> %val) vscale_range(1,1) {
|
||||
; CHECK-LABEL: store_fixed_no_divisible_offset_vscale_one:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: add x8, x0, #3
|
||||
; CHECK-NEXT: str p0, [x8]
|
||||
; CHECK-NEXT: ret
|
||||
%addr = getelementptr i8, ptr %base, i64 3
|
||||
store <vscale x 16 x i1> %val, ptr %addr, align 2
|
||||
ret void
|
||||
}
|
||||
|
||||
; -257 * sizeof(<vscale x 16 x i1>) == -514
|
||||
define <vscale x 16 x i1> @load_fixed_offset_too_low_vscale_one(ptr %base) vscale_range(1,1) {
|
||||
; CHECK-LABEL: load_fixed_offset_too_low_vscale_one:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: sub x8, x0, #514
|
||||
; CHECK-NEXT: ldr p0, [x8]
|
||||
; CHECK-NEXT: ret
|
||||
%addr = getelementptr i8, ptr %base, i64 -514
|
||||
%val = load <vscale x 16 x i1>, ptr %addr, align 2
|
||||
ret <vscale x 16 x i1> %val
|
||||
}
|
||||
|
||||
; 256 * sizeof(<vscale x 16 x i1>) == 1024
|
||||
define void @store_fixed_offset_too_high_vscale_two(ptr %base, <vscale x 16 x i1> %val) vscale_range(2,2) {
|
||||
; CHECK-LABEL: store_fixed_offset_too_high_vscale_two:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: add x8, x0, #1024
|
||||
; CHECK-NEXT: str p0, [x8]
|
||||
; CHECK-NEXT: ret
|
||||
%addr = getelementptr i8, ptr %base, i64 1024
|
||||
store <vscale x 16 x i1> %val, ptr %addr, align 2
|
||||
ret void
|
||||
}
|
||||
Reference in new issue
Block a user