Skip to content

Commit 19f5da9

Browse files
[SVE][Codegen] Lower legal min & max operations
Summary: This patch adds AArch64ISD nodes for [S|U]MIN_PRED and [S|U]MAX_PRED, and lowers both SVE intrinsics and IR operations for min and max to these nodes. There are two forms of these instructions for SVE: a predicated form and an immediate (unpredicated) form. The patterns which existed for the latter have been updated to match a predicated node with an immediate and map this to the immediate instruction. Reviewers: sdesmalen, efriedma, dancgr, rengolin Reviewed By: efriedma Subscribers: huihuiz, tschuett, kristof.beyls, hiraditya, rkruppe, psnobl, cfe-commits, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D79087
1 parent e737847 commit 19f5da9

7 files changed

+484
-30
lines changed

llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3092,7 +3092,7 @@ bool AArch64DAGToDAGISel::SelectSVESignedArithImm(SDValue N, SDValue &Imm) {
30923092
if (auto CNode = dyn_cast<ConstantSDNode>(N)) {
30933093
int64_t ImmVal = CNode->getSExtValue();
30943094
SDLoc DL(N);
3095-
if (ImmVal >= -127 && ImmVal < 127) {
3095+
if (ImmVal >= -128 && ImmVal < 128) {
30963096
Imm = CurDAG->getTargetConstant(ImmVal, DL, MVT::i32);
30973097
return true;
30983098
}

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -188,10 +188,6 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
188188
setOperationAction(ISD::UADDSAT, VT, Legal);
189189
setOperationAction(ISD::SSUBSAT, VT, Legal);
190190
setOperationAction(ISD::USUBSAT, VT, Legal);
191-
setOperationAction(ISD::SMAX, VT, Legal);
192-
setOperationAction(ISD::UMAX, VT, Legal);
193-
setOperationAction(ISD::SMIN, VT, Legal);
194-
setOperationAction(ISD::UMIN, VT, Legal);
195191
}
196192

197193
for (auto VT :
@@ -887,6 +883,10 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
887883
setOperationAction(ISD::SPLAT_VECTOR, VT, Custom);
888884
setOperationAction(ISD::SDIV, VT, Custom);
889885
setOperationAction(ISD::UDIV, VT, Custom);
886+
setOperationAction(ISD::SMIN, VT, Custom);
887+
setOperationAction(ISD::UMIN, VT, Custom);
888+
setOperationAction(ISD::SMAX, VT, Custom);
889+
setOperationAction(ISD::UMAX, VT, Custom);
890890
}
891891
}
892892
setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i8, Custom);
@@ -1285,6 +1285,10 @@ const char *AArch64TargetLowering::getTargetNodeName(unsigned Opcode) const {
12851285
case AArch64ISD::TLSDESC_CALLSEQ: return "AArch64ISD::TLSDESC_CALLSEQ";
12861286
case AArch64ISD::SDIV_PRED: return "AArch64ISD::SDIV_PRED";
12871287
case AArch64ISD::UDIV_PRED: return "AArch64ISD::UDIV_PRED";
1288+
case AArch64ISD::SMIN_PRED: return "AArch64ISD::SMIN_PRED";
1289+
case AArch64ISD::UMIN_PRED: return "AArch64ISD::UMIN_PRED";
1290+
case AArch64ISD::SMAX_PRED: return "AArch64ISD::SMAX_PRED";
1291+
case AArch64ISD::UMAX_PRED: return "AArch64ISD::UMAX_PRED";
12881292
case AArch64ISD::ADC: return "AArch64ISD::ADC";
12891293
case AArch64ISD::SBC: return "AArch64ISD::SBC";
12901294
case AArch64ISD::ADDS: return "AArch64ISD::ADDS";
@@ -3354,9 +3358,17 @@ SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
33543358
case ISD::EXTRACT_SUBVECTOR:
33553359
return LowerEXTRACT_SUBVECTOR(Op, DAG);
33563360
case ISD::SDIV:
3357-
return LowerDIV(Op, DAG, AArch64ISD::SDIV_PRED);
3361+
return LowerToPredicatedOp(Op, DAG, AArch64ISD::SDIV_PRED);
33583362
case ISD::UDIV:
3359-
return LowerDIV(Op, DAG, AArch64ISD::UDIV_PRED);
3363+
return LowerToPredicatedOp(Op, DAG, AArch64ISD::UDIV_PRED);
3364+
case ISD::SMIN:
3365+
return LowerToPredicatedOp(Op, DAG, AArch64ISD::SMIN_PRED);
3366+
case ISD::UMIN:
3367+
return LowerToPredicatedOp(Op, DAG, AArch64ISD::UMIN_PRED);
3368+
case ISD::SMAX:
3369+
return LowerToPredicatedOp(Op, DAG, AArch64ISD::SMAX_PRED);
3370+
case ISD::UMAX:
3371+
return LowerToPredicatedOp(Op, DAG, AArch64ISD::UMAX_PRED);
33603372
case ISD::SRA:
33613373
case ISD::SRL:
33623374
case ISD::SHL:
@@ -7663,7 +7675,7 @@ SDValue AArch64TargetLowering::LowerDUPQLane(SDValue Op,
76637675
return DAG.getNode(ISD::BITCAST, DL, VT, TBL);
76647676
}
76657677

7666-
SDValue AArch64TargetLowering::LowerDIV(SDValue Op,
7678+
SDValue AArch64TargetLowering::LowerToPredicatedOp(SDValue Op,
76677679
SelectionDAG &DAG,
76687680
unsigned NewOp) const {
76697681
EVT VT = Op.getValueType();
@@ -11435,7 +11447,19 @@ static SDValue performIntrinsicCombine(SDNode *N,
1143511447
return DAG.getNode(AArch64ISD::SDIV_PRED, SDLoc(N), N->getValueType(0),
1143611448
N->getOperand(1), N->getOperand(2), N->getOperand(3));
1143711449
case Intrinsic::aarch64_sve_udiv:
11438-
return DAG.getNode(AArch64ISD::UDIV_PRED, SDLoc(N), N->getValueType(0),
11450+
return DAG.getNode(AArch64ISD::UDIV_PRED, SDLoc(N), N->getValueType(0),
11451+
N->getOperand(1), N->getOperand(2), N->getOperand(3));
11452+
case Intrinsic::aarch64_sve_smin:
11453+
return DAG.getNode(AArch64ISD::SMIN_PRED, SDLoc(N), N->getValueType(0),
11454+
N->getOperand(1), N->getOperand(2), N->getOperand(3));
11455+
case Intrinsic::aarch64_sve_umin:
11456+
return DAG.getNode(AArch64ISD::UMIN_PRED, SDLoc(N), N->getValueType(0),
11457+
N->getOperand(1), N->getOperand(2), N->getOperand(3));
11458+
case Intrinsic::aarch64_sve_smax:
11459+
return DAG.getNode(AArch64ISD::SMAX_PRED, SDLoc(N), N->getValueType(0),
11460+
N->getOperand(1), N->getOperand(2), N->getOperand(3));
11461+
case Intrinsic::aarch64_sve_umax:
11462+
return DAG.getNode(AArch64ISD::UMAX_PRED, SDLoc(N), N->getValueType(0),
1143911463
N->getOperand(1), N->getOperand(2), N->getOperand(3));
1144011464
case Intrinsic::aarch64_sve_fadda:
1144111465
return combineSVEReductionOrderedFP(N, AArch64ISD::FADDA_PRED, DAG);

llvm/lib/Target/AArch64/AArch64ISelLowering.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ enum NodeType : unsigned {
5555
// Arithmetic instructions
5656
SDIV_PRED,
5757
UDIV_PRED,
58+
SMIN_PRED,
59+
UMIN_PRED,
60+
SMAX_PRED,
61+
UMAX_PRED,
5862

5963
// Arithmetic instructions which write flags.
6064
ADDS,
@@ -793,8 +797,8 @@ class AArch64TargetLowering : public TargetLowering {
793797
SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const;
794798
SDValue LowerSPLAT_VECTOR(SDValue Op, SelectionDAG &DAG) const;
795799
SDValue LowerDUPQLane(SDValue Op, SelectionDAG &DAG) const;
796-
SDValue LowerDIV(SDValue Op, SelectionDAG &DAG,
797-
unsigned NewOp) const;
800+
SDValue LowerToPredicatedOp(SDValue Op, SelectionDAG &DAG,
801+
unsigned NewOp) const;
798802
SDValue LowerEXTRACT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const;
799803
SDValue LowerVectorSRA_SRL_SHL(SDValue Op, SelectionDAG &DAG) const;
800804
SDValue LowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const;

llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -149,13 +149,17 @@ def AArch64andv_pred : SDNode<"AArch64ISD::ANDV_PRED", SDT_AArch64Reduce>;
149149
def AArch64lasta : SDNode<"AArch64ISD::LASTA", SDT_AArch64Reduce>;
150150
def AArch64lastb : SDNode<"AArch64ISD::LASTB", SDT_AArch64Reduce>;
151151

152-
def SDT_AArch64DIV : SDTypeProfile<1, 3, [
152+
def SDT_AArch64Arith : SDTypeProfile<1, 3, [
153153
SDTCisVec<0>, SDTCisVec<1>, SDTCisVec<2>, SDTCisVec<3>,
154154
SDTCVecEltisVT<1,i1>, SDTCisSameAs<2,3>
155155
]>;
156156

157-
def AArch64sdiv_pred : SDNode<"AArch64ISD::SDIV_PRED", SDT_AArch64DIV>;
158-
def AArch64udiv_pred : SDNode<"AArch64ISD::UDIV_PRED", SDT_AArch64DIV>;
157+
def AArch64sdiv_pred : SDNode<"AArch64ISD::SDIV_PRED", SDT_AArch64Arith>;
158+
def AArch64udiv_pred : SDNode<"AArch64ISD::UDIV_PRED", SDT_AArch64Arith>;
159+
def AArch64smin_pred : SDNode<"AArch64ISD::SMIN_PRED", SDT_AArch64Arith>;
160+
def AArch64umin_pred : SDNode<"AArch64ISD::UMIN_PRED", SDT_AArch64Arith>;
161+
def AArch64smax_pred : SDNode<"AArch64ISD::SMAX_PRED", SDT_AArch64Arith>;
162+
def AArch64umax_pred : SDNode<"AArch64ISD::UMAX_PRED", SDT_AArch64Arith>;
159163

160164
def SDT_AArch64ReduceWithInit : SDTypeProfile<1, 3, [SDTCisVec<1>, SDTCisVec<3>]>;
161165
def AArch64clasta_n : SDNode<"AArch64ISD::CLASTA_N", SDT_AArch64ReduceWithInit>;
@@ -232,10 +236,10 @@ let Predicates = [HasSVE] in {
232236
defm EOR_ZI : sve_int_log_imm<0b01, "eor", "eon", xor>;
233237
defm AND_ZI : sve_int_log_imm<0b10, "and", "bic", and>;
234238

235-
defm SMAX_ZI : sve_int_arith_imm1<0b00, "smax", smax>;
236-
defm SMIN_ZI : sve_int_arith_imm1<0b10, "smin", smin>;
237-
defm UMAX_ZI : sve_int_arith_imm1_unsigned<0b01, "umax", umax>;
238-
defm UMIN_ZI : sve_int_arith_imm1_unsigned<0b11, "umin", umin>;
239+
defm SMAX_ZI : sve_int_arith_imm1<0b00, "smax", AArch64smax_pred>;
240+
defm SMIN_ZI : sve_int_arith_imm1<0b10, "smin", AArch64smin_pred>;
241+
defm UMAX_ZI : sve_int_arith_imm1_unsigned<0b01, "umax", AArch64umax_pred>;
242+
defm UMIN_ZI : sve_int_arith_imm1_unsigned<0b11, "umin", AArch64umin_pred>;
239243

240244
defm MUL_ZI : sve_int_arith_imm2<"mul", mul>;
241245
defm MUL_ZPmZ : sve_int_bin_pred_arit_2<0b000, "mul", int_aarch64_sve_mul>;
@@ -280,10 +284,10 @@ let Predicates = [HasSVE] in {
280284
defm FABS_ZPmZ : sve_int_un_pred_arit_1_fp<0b100, "fabs", int_aarch64_sve_fabs>;
281285
defm FNEG_ZPmZ : sve_int_un_pred_arit_1_fp<0b101, "fneg", int_aarch64_sve_fneg>;
282286

283-
defm SMAX_ZPmZ : sve_int_bin_pred_arit_1<0b000, "smax", int_aarch64_sve_smax>;
284-
defm UMAX_ZPmZ : sve_int_bin_pred_arit_1<0b001, "umax", int_aarch64_sve_umax>;
285-
defm SMIN_ZPmZ : sve_int_bin_pred_arit_1<0b010, "smin", int_aarch64_sve_smin>;
286-
defm UMIN_ZPmZ : sve_int_bin_pred_arit_1<0b011, "umin", int_aarch64_sve_umin>;
287+
defm SMAX_ZPmZ : sve_int_bin_pred_arit_1<0b000, "smax", AArch64smax_pred>;
288+
defm UMAX_ZPmZ : sve_int_bin_pred_arit_1<0b001, "umax", AArch64umax_pred>;
289+
defm SMIN_ZPmZ : sve_int_bin_pred_arit_1<0b010, "smin", AArch64smin_pred>;
290+
defm UMIN_ZPmZ : sve_int_bin_pred_arit_1<0b011, "umin", AArch64umin_pred>;
287291
defm SABD_ZPmZ : sve_int_bin_pred_arit_1<0b100, "sabd", int_aarch64_sve_sabd>;
288292
defm UABD_ZPmZ : sve_int_bin_pred_arit_1<0b101, "uabd", int_aarch64_sve_uabd>;
289293

llvm/lib/Target/AArch64/SVEInstrFormats.td

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,11 @@ class SVE_1_Op_Imm_Arith_Pat<ValueType vt, SDPatternOperator op, ZPRRegOp zprty,
324324
: Pat<(vt (op (vt zprty:$Op1), (vt (AArch64dup (it (cpx i32:$imm)))))),
325325
(inst $Op1, i32:$imm)>;
326326

327+
class SVE_1_Op_Imm_Arith_Pred_Pat<ValueType vt, ValueType pt, SDPatternOperator op,
328+
ZPRRegOp zprty, ValueType it, ComplexPattern cpx, Instruction inst>
329+
: Pat<(vt (op (pt (AArch64ptrue 31)), (vt zprty:$Op1), (vt (AArch64dup (it (cpx i32:$imm)))))),
330+
(inst $Op1, i32:$imm)>;
331+
327332
class SVE_1_Op_Imm_Log_Pat<ValueType vt, SDPatternOperator op, ZPRRegOp zprty,
328333
ValueType it, ComplexPattern cpx, Instruction inst>
329334
: Pat<(vt (op (vt zprty:$Op1), (vt (AArch64dup (it (cpx i64:$imm)))))),
@@ -3840,10 +3845,10 @@ multiclass sve_int_arith_imm1<bits<2> opc, string asm, SDPatternOperator op> {
38403845
def _S : sve_int_arith_imm<0b10, { 0b1010, opc }, asm, ZPR32, simm8>;
38413846
def _D : sve_int_arith_imm<0b11, { 0b1010, opc }, asm, ZPR64, simm8>;
38423847

3843-
def : SVE_1_Op_Imm_Arith_Pat<nxv16i8, op, ZPR8, i32, SVEArithSImmPat, !cast<Instruction>(NAME # _B)>;
3844-
def : SVE_1_Op_Imm_Arith_Pat<nxv8i16, op, ZPR16, i32, SVEArithSImmPat, !cast<Instruction>(NAME # _H)>;
3845-
def : SVE_1_Op_Imm_Arith_Pat<nxv4i32, op, ZPR32, i32, SVEArithSImmPat, !cast<Instruction>(NAME # _S)>;
3846-
def : SVE_1_Op_Imm_Arith_Pat<nxv2i64, op, ZPR64, i64, SVEArithSImmPat, !cast<Instruction>(NAME # _D)>;
3848+
def : SVE_1_Op_Imm_Arith_Pred_Pat<nxv16i8, nxv16i1, op, ZPR8, i32, SVEArithSImmPat, !cast<Instruction>(NAME # _B)>;
3849+
def : SVE_1_Op_Imm_Arith_Pred_Pat<nxv8i16, nxv8i1, op, ZPR16, i32, SVEArithSImmPat, !cast<Instruction>(NAME # _H)>;
3850+
def : SVE_1_Op_Imm_Arith_Pred_Pat<nxv4i32, nxv4i1, op, ZPR32, i32, SVEArithSImmPat, !cast<Instruction>(NAME # _S)>;
3851+
def : SVE_1_Op_Imm_Arith_Pred_Pat<nxv2i64, nxv2i1, op, ZPR64, i64, SVEArithSImmPat, !cast<Instruction>(NAME # _D)>;
38473852
}
38483853

38493854
multiclass sve_int_arith_imm1_unsigned<bits<2> opc, string asm, SDPatternOperator op> {
@@ -3852,10 +3857,10 @@ multiclass sve_int_arith_imm1_unsigned<bits<2> opc, string asm, SDPatternOperato
38523857
def _S : sve_int_arith_imm<0b10, { 0b1010, opc }, asm, ZPR32, imm0_255>;
38533858
def _D : sve_int_arith_imm<0b11, { 0b1010, opc }, asm, ZPR64, imm0_255>;
38543859

3855-
def : SVE_1_Op_Imm_Arith_Pat<nxv16i8, op, ZPR8, i32, SVEArithUImmPat, !cast<Instruction>(NAME # _B)>;
3856-
def : SVE_1_Op_Imm_Arith_Pat<nxv8i16, op, ZPR16, i32, SVEArithUImmPat, !cast<Instruction>(NAME # _H)>;
3857-
def : SVE_1_Op_Imm_Arith_Pat<nxv4i32, op, ZPR32, i32, SVEArithUImmPat, !cast<Instruction>(NAME # _S)>;
3858-
def : SVE_1_Op_Imm_Arith_Pat<nxv2i64, op, ZPR64, i64, SVEArithUImmPat, !cast<Instruction>(NAME # _D)>;
3860+
def : SVE_1_Op_Imm_Arith_Pred_Pat<nxv16i8, nxv16i1, op, ZPR8, i32, SVEArithUImmPat, !cast<Instruction>(NAME # _B)>;
3861+
def : SVE_1_Op_Imm_Arith_Pred_Pat<nxv8i16, nxv8i1, op, ZPR16, i32, SVEArithUImmPat, !cast<Instruction>(NAME # _H)>;
3862+
def : SVE_1_Op_Imm_Arith_Pred_Pat<nxv4i32, nxv4i1, op, ZPR32, i32, SVEArithUImmPat, !cast<Instruction>(NAME # _S)>;
3863+
def : SVE_1_Op_Imm_Arith_Pred_Pat<nxv2i64, nxv2i1, op, ZPR64, i64, SVEArithUImmPat, !cast<Instruction>(NAME # _D)>;
38593864
}
38603865

38613866
multiclass sve_int_arith_imm2<string asm, SDPatternOperator op> {

llvm/test/CodeGen/AArch64/llvm-ir-to-intrinsic.ll

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,179 @@ define <vscale x 2 x i64> @udiv_i64(<vscale x 2 x i64> %a, <vscale x 2 x i64> %b
4343
%div = udiv <vscale x 2 x i64> %a, %b
4444
ret <vscale x 2 x i64> %div
4545
}
46+
47+
;
48+
; SMIN
49+
;
50+
51+
define <vscale x 16 x i8> @smin_i8(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b, <vscale x 16 x i8> %c) {
52+
; CHECK-LABEL: @smin_i8
53+
; CHECK-DAG: ptrue p0.b
54+
; CHECK-DAG: smin z0.b, p0/m, z0.b, z1.b
55+
; CHECK-NEXT: ret
56+
%cmp = icmp slt <vscale x 16 x i8> %a, %b
57+
%min = select <vscale x 16 x i1> %cmp, <vscale x 16 x i8> %a, <vscale x 16 x i8> %b
58+
ret <vscale x 16 x i8> %min
59+
}
60+
61+
define <vscale x 8 x i16> @smin_i16(<vscale x 8 x i16> %a, <vscale x 8 x i16> %b, <vscale x 8 x i16> %c) {
62+
; CHECK-LABEL: @smin_i16
63+
; CHECK-DAG: ptrue p0.h
64+
; CHECK-DAG: smin z0.h, p0/m, z0.h, z1.h
65+
; CHECK-NEXT: ret
66+
%cmp = icmp slt <vscale x 8 x i16> %a, %b
67+
%min = select <vscale x 8 x i1> %cmp, <vscale x 8 x i16> %a, <vscale x 8 x i16> %b
68+
ret <vscale x 8 x i16> %min
69+
}
70+
71+
define <vscale x 4 x i32> @smin_i32(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b, <vscale x 4 x i32> %c) {
72+
; CHECK-LABEL: smin_i32:
73+
; CHECK-DAG: ptrue p0.s
74+
; CHECK-DAG: smin z0.s, p0/m, z0.s, z1.s
75+
; CHECK-NEXT: ret
76+
%cmp = icmp slt <vscale x 4 x i32> %a, %b
77+
%min = select <vscale x 4 x i1> %cmp, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b
78+
ret <vscale x 4 x i32> %min
79+
}
80+
81+
define <vscale x 2 x i64> @smin_i64(<vscale x 2 x i64> %a, <vscale x 2 x i64> %b, <vscale x 2 x i64> %c) {
82+
; CHECK-LABEL: smin_i64:
83+
; CHECK-DAG: ptrue p0.d
84+
; CHECK-DAG: smin z0.d, p0/m, z0.d, z1.d
85+
; CHECK-NEXT: ret
86+
%cmp = icmp slt <vscale x 2 x i64> %a, %b
87+
%min = select <vscale x 2 x i1> %cmp, <vscale x 2 x i64> %a, <vscale x 2 x i64> %b
88+
ret <vscale x 2 x i64> %min
89+
}
90+
91+
;
92+
; UMIN
93+
;
94+
95+
define <vscale x 16 x i8> @umin_i8(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b, <vscale x 16 x i8> %c) {
96+
; CHECK-LABEL: @umin_i8
97+
; CHECK-DAG: ptrue p0.b
98+
; CHECK-DAG: umin z0.b, p0/m, z0.b, z1.b
99+
; CHECK-NEXT: ret
100+
%cmp = icmp ult <vscale x 16 x i8> %a, %b
101+
%min = select <vscale x 16 x i1> %cmp, <vscale x 16 x i8> %a, <vscale x 16 x i8> %b
102+
ret <vscale x 16 x i8> %min
103+
}
104+
105+
define <vscale x 8 x i16> @umin_i16(<vscale x 8 x i16> %a, <vscale x 8 x i16> %b, <vscale x 8 x i16> %c) {
106+
; CHECK-LABEL: @umin_i16
107+
; CHECK-DAG: ptrue p0.h
108+
; CHECK-DAG: umin z0.h, p0/m, z0.h, z1.h
109+
; CHECK-NEXT: ret
110+
%cmp = icmp ult <vscale x 8 x i16> %a, %b
111+
%min = select <vscale x 8 x i1> %cmp, <vscale x 8 x i16> %a, <vscale x 8 x i16> %b
112+
ret <vscale x 8 x i16> %min
113+
}
114+
115+
define <vscale x 4 x i32> @umin_i32(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b, <vscale x 4 x i32> %c) {
116+
; CHECK-LABEL: umin_i32:
117+
; CHECK-DAG: ptrue p0.s
118+
; CHECK-DAG: umin z0.s, p0/m, z0.s, z1.s
119+
; CHECK-NEXT: ret
120+
%cmp = icmp ult <vscale x 4 x i32> %a, %b
121+
%min = select <vscale x 4 x i1> %cmp, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b
122+
ret <vscale x 4 x i32> %min
123+
}
124+
125+
define <vscale x 2 x i64> @umin_i64(<vscale x 2 x i64> %a, <vscale x 2 x i64> %b, <vscale x 2 x i64> %c) {
126+
; CHECK-LABEL: umin_i64:
127+
; CHECK-DAG: ptrue p0.d
128+
; CHECK-DAG: umin z0.d, p0/m, z0.d, z1.d
129+
; CHECK-NEXT: ret
130+
%cmp = icmp ult <vscale x 2 x i64> %a, %b
131+
%min = select <vscale x 2 x i1> %cmp, <vscale x 2 x i64> %a, <vscale x 2 x i64> %b
132+
ret <vscale x 2 x i64> %min
133+
}
134+
135+
;
136+
; SMAX
137+
;
138+
139+
define <vscale x 16 x i8> @smax_i8(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b, <vscale x 16 x i8> %c) {
140+
; CHECK-LABEL: @smax_i8
141+
; CHECK-DAG: ptrue p0.b
142+
; CHECK-DAG: smax z0.b, p0/m, z0.b, z1.b
143+
; CHECK-NEXT: ret
144+
%cmp = icmp sgt <vscale x 16 x i8> %a, %b
145+
%min = select <vscale x 16 x i1> %cmp, <vscale x 16 x i8> %a, <vscale x 16 x i8> %b
146+
ret <vscale x 16 x i8> %min
147+
}
148+
149+
define <vscale x 8 x i16> @smax_i16(<vscale x 8 x i16> %a, <vscale x 8 x i16> %b, <vscale x 8 x i16> %c) {
150+
; CHECK-LABEL: @smax_i16
151+
; CHECK-DAG: ptrue p0.h
152+
; CHECK-DAG: smax z0.h, p0/m, z0.h, z1.h
153+
; CHECK-NEXT: ret
154+
%cmp = icmp sgt <vscale x 8 x i16> %a, %b
155+
%min = select <vscale x 8 x i1> %cmp, <vscale x 8 x i16> %a, <vscale x 8 x i16> %b
156+
ret <vscale x 8 x i16> %min
157+
}
158+
159+
define <vscale x 4 x i32> @smax_i32(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b, <vscale x 4 x i32> %c) {
160+
; CHECK-LABEL: smax_i32:
161+
; CHECK-DAG: ptrue p0.s
162+
; CHECK-DAG: smax z0.s, p0/m, z0.s, z1.s
163+
; CHECK-NEXT: ret
164+
%cmp = icmp sgt <vscale x 4 x i32> %a, %b
165+
%min = select <vscale x 4 x i1> %cmp, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b
166+
ret <vscale x 4 x i32> %min
167+
}
168+
169+
define <vscale x 2 x i64> @smax_i64(<vscale x 2 x i64> %a, <vscale x 2 x i64> %b, <vscale x 2 x i64> %c) {
170+
; CHECK-LABEL: smax_i64:
171+
; CHECK-DAG: ptrue p0.d
172+
; CHECK-DAG: smax z0.d, p0/m, z0.d, z1.d
173+
; CHECK-NEXT: ret
174+
%cmp = icmp sgt <vscale x 2 x i64> %a, %b
175+
%min = select <vscale x 2 x i1> %cmp, <vscale x 2 x i64> %a, <vscale x 2 x i64> %b
176+
ret <vscale x 2 x i64> %min
177+
}
178+
179+
;
180+
; UMAX
181+
;
182+
183+
define <vscale x 16 x i8> @umax_i8(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b, <vscale x 16 x i8> %c) {
184+
; CHECK-LABEL: @umax_i8
185+
; CHECK-DAG: ptrue p0.b
186+
; CHECK-DAG: umax z0.b, p0/m, z0.b, z1.b
187+
; CHECK-NEXT: ret
188+
%cmp = icmp ugt <vscale x 16 x i8> %a, %b
189+
%min = select <vscale x 16 x i1> %cmp, <vscale x 16 x i8> %a, <vscale x 16 x i8> %b
190+
ret <vscale x 16 x i8> %min
191+
}
192+
193+
define <vscale x 8 x i16> @umax_i16(<vscale x 8 x i16> %a, <vscale x 8 x i16> %b, <vscale x 8 x i16> %c) {
194+
; CHECK-LABEL: @umax_i16
195+
; CHECK-DAG: ptrue p0.h
196+
; CHECK-DAG: umax z0.h, p0/m, z0.h, z1.h
197+
; CHECK-NEXT: ret
198+
%cmp = icmp ugt <vscale x 8 x i16> %a, %b
199+
%min = select <vscale x 8 x i1> %cmp, <vscale x 8 x i16> %a, <vscale x 8 x i16> %b
200+
ret <vscale x 8 x i16> %min
201+
}
202+
203+
define <vscale x 4 x i32> @umax_i32(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b, <vscale x 4 x i32> %c) {
204+
; CHECK-LABEL: umax_i32:
205+
; CHECK-DAG: ptrue p0.s
206+
; CHECK-DAG: umax z0.s, p0/m, z0.s, z1.s
207+
; CHECK-NEXT: ret
208+
%cmp = icmp ugt <vscale x 4 x i32> %a, %b
209+
%min = select <vscale x 4 x i1> %cmp, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b
210+
ret <vscale x 4 x i32> %min
211+
}
212+
213+
define <vscale x 2 x i64> @umax_i64(<vscale x 2 x i64> %a, <vscale x 2 x i64> %b, <vscale x 2 x i64> %c) {
214+
; CHECK-LABEL: umax_i64:
215+
; CHECK-DAG: ptrue p0.d
216+
; CHECK-DAG: umax z0.d, p0/m, z0.d, z1.d
217+
; CHECK-NEXT: ret
218+
%cmp = icmp ugt <vscale x 2 x i64> %a, %b
219+
%min = select <vscale x 2 x i1> %cmp, <vscale x 2 x i64> %a, <vscale x 2 x i64> %b
220+
ret <vscale x 2 x i64> %min
221+
}

0 commit comments

Comments
 (0)