From 76c76e9ab40d0c6d53587c81740ec9c6c2fdfcff Mon Sep 17 00:00:00 2001 From: "Kazushi (Jam) Marukawa" Date: Sat, 24 Sep 2022 14:51:07 +0900 Subject: [PATCH] [VE] Support smax/smin Support smax/smin in VEInstrInfo.td. Remove obsolete patterns for smax/smin. Add regression tests for smax/smin/umax/umin. Reviewed By: efocht Differential Revision: https://reviews.llvm.org/D134583 --- llvm/lib/Target/VE/VEISelLowering.cpp | 4 + llvm/lib/Target/VE/VEInstrInfo.td | 24 +-- llvm/test/CodeGen/VE/Scalar/atomic.ll | 26 +-- llvm/test/CodeGen/VE/Scalar/smax.ll | 337 +++++++++++++++++++++++++++++++ llvm/test/CodeGen/VE/Scalar/smin.ll | 337 +++++++++++++++++++++++++++++++ llvm/test/CodeGen/VE/Scalar/umax.ll | 358 +++++++++++++++++++++++++++++++++ llvm/test/CodeGen/VE/Scalar/umin.ll | 368 ++++++++++++++++++++++++++++++++++ 7 files changed, 1419 insertions(+), 35 deletions(-) create mode 100644 llvm/test/CodeGen/VE/Scalar/smax.ll create mode 100644 llvm/test/CodeGen/VE/Scalar/smin.ll create mode 100644 llvm/test/CodeGen/VE/Scalar/umax.ll create mode 100644 llvm/test/CodeGen/VE/Scalar/umin.ll diff --git a/llvm/lib/Target/VE/VEISelLowering.cpp b/llvm/lib/Target/VE/VEISelLowering.cpp index 8c2763c..2c87492 100644 --- a/llvm/lib/Target/VE/VEISelLowering.cpp +++ b/llvm/lib/Target/VE/VEISelLowering.cpp @@ -201,6 +201,10 @@ void VETargetLowering::initSPUActions() { setOperationAction(ISD::AND, IntVT, Act); setOperationAction(ISD::OR, IntVT, Act); setOperationAction(ISD::XOR, IntVT, Act); + + // Legal smax and smin + setOperationAction(ISD::SMAX, IntVT, Legal); + setOperationAction(ISD::SMIN, IntVT, Legal); } /// } Int Ops diff --git a/llvm/lib/Target/VE/VEInstrInfo.td b/llvm/lib/Target/VE/VEInstrInfo.td index 528bebd..cd3fe34 100644 --- a/llvm/lib/Target/VE/VEInstrInfo.td +++ b/llvm/lib/Target/VE/VEInstrInfo.td @@ -1237,14 +1237,14 @@ defm CMPSL : RRNCm<"cmps.l", 0x6A, I64, i64>; // Section 8.4.17 - CMS (Compare and Select Maximum/Minimum Single) // cx: sx/zx, cw: max/min -defm MAXSWSX : RRm<"maxs.w.sx", 0x78, I32, i32>; +defm MAXSWSX : RRm<"maxs.w.sx", 0x78, I32, i32, smax>; let cx = 1 in defm MAXSWZX : RRm<"maxs.w.zx", 0x78, I32, i32>; -let cw = 1 in defm MINSWSX : RRm<"mins.w.sx", 0x78, I32, i32>; +let cw = 1 in defm MINSWSX : RRm<"mins.w.sx", 0x78, I32, i32, smin>; let cx = 1, cw = 1 in defm MINSWZX : RRm<"mins.w.zx", 0x78, I32, i32>; // Section 8.4.18 - CMX (Compare and Select Maximum/Minimum) -defm MAXSL : RRm<"maxs.l", 0x68, I64, i64>; -let cw = 1 in defm MINSL : RRm<"mins.l", 0x68, I64, i64>; +defm MAXSL : RRm<"maxs.l", 0x68, I64, i64, smax>; +let cw = 1 in defm MINSL : RRm<"mins.l", 0x68, I64, i64, smin>; } // isReMaterializable, isAsCheapAsAMove @@ -2061,35 +2061,19 @@ def : Pat<(f64 (selectcc f64:$LHS, f64:$RHS, f64:$LHS, f64:$RHS, SETOGT)), (FMAXDrr $LHS, $RHS)>; def : Pat<(f32 (selectcc f32:$LHS, f32:$RHS, f32:$LHS, f32:$RHS, SETOGT)), (FMAXSrr $LHS, $RHS)>; -def : Pat<(i64 (selectcc i64:$LHS, i64:$RHS, i64:$LHS, i64:$RHS, SETGT)), - (MAXSLrr $LHS, $RHS)>; -def : Pat<(i32 (selectcc i32:$LHS, i32:$RHS, i32:$LHS, i32:$RHS, SETGT)), - (MAXSWSXrr $LHS, $RHS)>; def : Pat<(f64 (selectcc f64:$LHS, f64:$RHS, f64:$LHS, f64:$RHS, SETOGE)), (FMAXDrr $LHS, $RHS)>; def : Pat<(f32 (selectcc f32:$LHS, f32:$RHS, f32:$LHS, f32:$RHS, SETOGE)), (FMAXSrr $LHS, $RHS)>; -def : Pat<(i64 (selectcc i64:$LHS, i64:$RHS, i64:$LHS, i64:$RHS, SETGE)), - (MAXSLrr $LHS, $RHS)>; -def : Pat<(i32 (selectcc i32:$LHS, i32:$RHS, i32:$LHS, i32:$RHS, SETGE)), - (MAXSWSXrr $LHS, $RHS)>; def : Pat<(f64 (selectcc f64:$LHS, f64:$RHS, f64:$LHS, f64:$RHS, SETOLT)), (FMINDrr $LHS, $RHS)>; def : Pat<(f32 (selectcc f32:$LHS, f32:$RHS, f32:$LHS, f32:$RHS, SETOLT)), (FMINSrr $LHS, $RHS)>; -def : Pat<(i64 (selectcc i64:$LHS, i64:$RHS, i64:$LHS, i64:$RHS, SETLT)), - (MINSLrr $LHS, $RHS)>; -def : Pat<(i32 (selectcc i32:$LHS, i32:$RHS, i32:$LHS, i32:$RHS, SETLT)), - (MINSWSXrr $LHS, $RHS)>; def : Pat<(f64 (selectcc f64:$LHS, f64:$RHS, f64:$LHS, f64:$RHS, SETOLE)), (FMINDrr $LHS, $RHS)>; def : Pat<(f32 (selectcc f32:$LHS, f32:$RHS, f32:$LHS, f32:$RHS, SETOLE)), (FMINSrr $LHS, $RHS)>; -def : Pat<(i64 (selectcc i64:$LHS, i64:$RHS, i64:$LHS, i64:$RHS, SETLE)), - (MINSLrr $LHS, $RHS)>; -def : Pat<(i32 (selectcc i32:$LHS, i32:$RHS, i32:$LHS, i32:$RHS, SETLE)), - (MINSWSXrr $LHS, $RHS)>; // Helper classes to construct cmov patterns for the ease. // diff --git a/llvm/test/CodeGen/VE/Scalar/atomic.ll b/llvm/test/CodeGen/VE/Scalar/atomic.ll index f01bf0f..405cdc3 100644 --- a/llvm/test/CodeGen/VE/Scalar/atomic.ll +++ b/llvm/test/CodeGen/VE/Scalar/atomic.ll @@ -184,13 +184,12 @@ define signext i32 @test_atomic_fetch_max_4() { ; CHECK-NEXT: and %s0, %s0, (32)0 ; CHECK-NEXT: lea.sl %s1, i@hi(, %s0) ; CHECK-NEXT: ldl.sx %s0, (, %s1) -; CHECK-NEXT: or %s2, 1, (0)1 ; CHECK-NEXT: .LBB6_1: # %atomicrmw.start ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 -; CHECK-NEXT: or %s3, 0, %s0 -; CHECK-NEXT: maxs.w.sx %s0, %s0, %s2 -; CHECK-NEXT: cas.w %s0, (%s1), %s3 -; CHECK-NEXT: brne.w %s0, %s3, .LBB6_1 +; CHECK-NEXT: or %s2, 0, %s0 +; CHECK-NEXT: maxs.w.sx %s0, 1, %s0 +; CHECK-NEXT: cas.w %s0, (%s1), %s2 +; CHECK-NEXT: brne.w %s0, %s2, .LBB6_1 ; CHECK-NEXT: # %bb.2: # %atomicrmw.end ; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1 ; CHECK-NEXT: fencem 3 @@ -207,19 +206,16 @@ define signext i32 @test_atomic_fetch_min_4() { ; CHECK-NEXT: fencem 3 ; CHECK-NEXT: lea %s0, i@lo ; CHECK-NEXT: and %s0, %s0, (32)0 -; CHECK-NEXT: lea.sl %s0, i@hi(, %s0) -; CHECK-NEXT: ldl.sx %s1, (, %s0) -; CHECK-NEXT: or %s2, 2, (0)1 +; CHECK-NEXT: lea.sl %s1, i@hi(, %s0) +; CHECK-NEXT: ldl.sx %s0, (, %s1) ; CHECK-NEXT: .LBB7_1: # %atomicrmw.start ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 -; CHECK-NEXT: or %s3, 0, %s1 -; CHECK-NEXT: cmps.w.sx %s4, %s1, %s2 -; CHECK-NEXT: or %s1, 1, (0)1 -; CHECK-NEXT: cmov.w.lt %s1, %s3, %s4 -; CHECK-NEXT: cas.w %s1, (%s0), %s3 -; CHECK-NEXT: brne.w %s1, %s3, .LBB7_1 +; CHECK-NEXT: or %s2, 0, %s0 +; CHECK-NEXT: mins.w.sx %s0, 1, %s0 +; CHECK-NEXT: cas.w %s0, (%s1), %s2 +; CHECK-NEXT: brne.w %s0, %s2, .LBB7_1 ; CHECK-NEXT: # %bb.2: # %atomicrmw.end -; CHECK-NEXT: adds.w.sx %s0, %s1, (0)1 +; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1 ; CHECK-NEXT: fencem 3 ; CHECK-NEXT: b.l.t (, %s10) entry: diff --git a/llvm/test/CodeGen/VE/Scalar/smax.ll b/llvm/test/CodeGen/VE/Scalar/smax.ll new file mode 100644 index 0000000..f989e04 --- /dev/null +++ b/llvm/test/CodeGen/VE/Scalar/smax.ll @@ -0,0 +1,337 @@ +; RUN: llc < %s -mtriple=ve | FileCheck %s + +;;; Test ‘llvm.smax.*’ intrinsic +;;; +;;; Syntax: +;;; This is an overloaded intrinsic. You can use @llvm.smax on any +;;; integer bit width or any vector of integer elements. +;;; +;;; declare i32 @llvm.smax.i32(i32 %a, i32 %b) +;;; declare <4 x i32> @llvm.smax.v4i32(<4 x i32> %a, <4 x i32> %b) +;;; +;;; Overview: +;;; Return the larger of %a and %b comparing the values as signed +;;; integers. Vector intrinsics operate on a per-element basis. +;;; The larger element of %a and %b at a given index is returned +;;; for that index. +;;; +;;; Arguments: +;;; The arguments (%a and %b) may be of any integer type or a vector +;;; with integer element type. The argument types must match each +;;; other, and the return type must match the argument type. +;;; +;;; Note: +;;; We test only i8/i16/i32/i64/i128. + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define signext i8 @func_smax_var_i8(i8 noundef signext %0, i8 noundef signext %1) { +; CHECK-LABEL: func_smax_var_i8: +; CHECK: # %bb.0: +; CHECK-NEXT: maxs.w.sx %s0, %s0, %s1 +; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %3 = tail call i8 @llvm.smax.i8(i8 %0, i8 %1) + ret i8 %3 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define signext i16 @func_smax_var_i16(i16 noundef signext %0, i16 noundef signext %1) { +; CHECK-LABEL: func_smax_var_i16: +; CHECK: # %bb.0: +; CHECK-NEXT: maxs.w.sx %s0, %s0, %s1 +; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %3 = tail call i16 @llvm.smax.i16(i16 %0, i16 %1) + ret i16 %3 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define signext i32 @func_smax_var_i32(i32 noundef signext %0, i32 noundef signext %1) { +; CHECK-LABEL: func_smax_var_i32: +; CHECK: # %bb.0: +; CHECK-NEXT: maxs.w.sx %s0, %s0, %s1 +; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %3 = tail call i32 @llvm.smax.i32(i32 %0, i32 %1) + ret i32 %3 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i64 @func_smax_var_i64(i64 noundef %0, i64 noundef %1) { +; CHECK-LABEL: func_smax_var_i64: +; CHECK: # %bb.0: +; CHECK-NEXT: maxs.l %s0, %s0, %s1 +; CHECK-NEXT: b.l.t (, %s10) + %3 = tail call i64 @llvm.smax.i64(i64 %0, i64 %1) + ret i64 %3 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i128 @func_smax_var_i128(i128 noundef %0, i128 noundef %1) { +; CHECK-LABEL: func_smax_var_i128: +; CHECK: # %bb.0: +; CHECK-NEXT: cmps.l %s5, %s1, %s3 +; CHECK-NEXT: or %s4, 0, %s2 +; CHECK-NEXT: cmov.l.gt %s4, %s0, %s5 +; CHECK-NEXT: cmpu.l %s6, %s0, %s2 +; CHECK-NEXT: cmov.l.gt %s2, %s0, %s6 +; CHECK-NEXT: cmov.l.eq %s4, %s2, %s5 +; CHECK-NEXT: maxs.l %s1, %s1, %s3 +; CHECK-NEXT: or %s0, 0, %s4 +; CHECK-NEXT: b.l.t (, %s10) + %3 = tail call i128 @llvm.smax.i128(i128 %0, i128 %1) + ret i128 %3 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define signext i8 @func_smax_fore_zero_i8(i8 noundef signext %0) { +; CHECK-LABEL: func_smax_fore_zero_i8: +; CHECK: # %bb.0: +; CHECK-NEXT: maxs.w.sx %s0, 0, %s0 +; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i8 @llvm.smax.i8(i8 %0, i8 0) + ret i8 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define signext i16 @func_smax_fore_zero_i16(i16 noundef signext %0) { +; CHECK-LABEL: func_smax_fore_zero_i16: +; CHECK: # %bb.0: +; CHECK-NEXT: maxs.w.sx %s0, 0, %s0 +; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i16 @llvm.smax.i16(i16 %0, i16 0) + ret i16 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define signext i32 @func_smax_fore_zero_i32(i32 noundef signext %0) { +; CHECK-LABEL: func_smax_fore_zero_i32: +; CHECK: # %bb.0: +; CHECK-NEXT: maxs.w.sx %s0, 0, %s0 +; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i32 @llvm.smax.i32(i32 %0, i32 0) + ret i32 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i64 @func_smax_fore_zero_i64(i64 noundef %0) { +; CHECK-LABEL: func_smax_fore_zero_i64: +; CHECK: # %bb.0: +; CHECK-NEXT: maxs.l %s0, 0, %s0 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i64 @llvm.smax.i64(i64 %0, i64 0) + ret i64 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i128 @func_smax_fore_zero_i128(i128 noundef %0) { +; CHECK-LABEL: func_smax_fore_zero_i128: +; CHECK: # %bb.0: +; CHECK-NEXT: or %s2, 0, (0)1 +; CHECK-NEXT: cmps.l %s3, %s1, (0)1 +; CHECK-NEXT: cmov.l.gt %s2, %s0, %s3 +; CHECK-NEXT: cmov.l.eq %s2, %s0, %s3 +; CHECK-NEXT: maxs.l %s1, 0, %s1 +; CHECK-NEXT: or %s0, 0, %s2 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i128 @llvm.smax.i128(i128 %0, i128 0) + ret i128 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define signext i8 @func_smax_back_zero_i8(i8 noundef signext %0) { +; CHECK-LABEL: func_smax_back_zero_i8: +; CHECK: # %bb.0: +; CHECK-NEXT: maxs.w.sx %s0, 0, %s0 +; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i8 @llvm.smax.i8(i8 %0, i8 0) + ret i8 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define signext i16 @func_smax_back_zero_i16(i16 noundef signext %0) { +; CHECK-LABEL: func_smax_back_zero_i16: +; CHECK: # %bb.0: +; CHECK-NEXT: maxs.w.sx %s0, 0, %s0 +; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i16 @llvm.smax.i16(i16 %0, i16 0) + ret i16 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define signext i32 @func_smax_back_zero_i32(i32 noundef signext %0) { +; CHECK-LABEL: func_smax_back_zero_i32: +; CHECK: # %bb.0: +; CHECK-NEXT: maxs.w.sx %s0, 0, %s0 +; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i32 @llvm.smax.i32(i32 %0, i32 0) + ret i32 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i64 @func_smax_back_zero_i64(i64 noundef %0) { +; CHECK-LABEL: func_smax_back_zero_i64: +; CHECK: # %bb.0: +; CHECK-NEXT: maxs.l %s0, 0, %s0 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i64 @llvm.smax.i64(i64 %0, i64 0) + ret i64 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i128 @func_smax_back_zero_i128(i128 noundef %0) { +; CHECK-LABEL: func_smax_back_zero_i128: +; CHECK: # %bb.0: +; CHECK-NEXT: or %s2, 0, (0)1 +; CHECK-NEXT: cmps.l %s3, %s1, (0)1 +; CHECK-NEXT: cmov.l.gt %s2, %s0, %s3 +; CHECK-NEXT: cmov.l.eq %s2, %s0, %s3 +; CHECK-NEXT: maxs.l %s1, 0, %s1 +; CHECK-NEXT: or %s0, 0, %s2 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i128 @llvm.smax.i128(i128 %0, i128 0) + ret i128 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define signext i8 @func_smax_fore_const_i8(i8 noundef signext %0) { +; CHECK-LABEL: func_smax_fore_const_i8: +; CHECK: # %bb.0: +; CHECK-NEXT: maxs.w.sx %s0, -1, %s0 +; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i8 @llvm.smax.i8(i8 %0, i8 -1) + ret i8 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define signext i16 @func_smax_fore_const_i16(i16 noundef signext %0) { +; CHECK-LABEL: func_smax_fore_const_i16: +; CHECK: # %bb.0: +; CHECK-NEXT: maxs.w.sx %s0, %s0, (56)0 +; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i16 @llvm.smax.i16(i16 %0, i16 255) + ret i16 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define signext i32 @func_smax_fore_const_i32(i32 noundef signext %0) { +; CHECK-LABEL: func_smax_fore_const_i32: +; CHECK: # %bb.0: +; CHECK-NEXT: maxs.w.sx %s0, %s0, (56)0 +; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i32 @llvm.smax.i32(i32 %0, i32 255) + ret i32 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i64 @func_smax_fore_const_i64(i64 noundef %0) { +; CHECK-LABEL: func_smax_fore_const_i64: +; CHECK: # %bb.0: +; CHECK-NEXT: maxs.l %s0, %s0, (56)0 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i64 @llvm.smax.i64(i64 %0, i64 255) + ret i64 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i128 @func_smax_fore_const_i128(i128 noundef %0) { +; CHECK-LABEL: func_smax_fore_const_i128: +; CHECK: # %bb.0: +; CHECK-NEXT: cmps.l %s3, %s1, (0)1 +; CHECK-NEXT: lea %s4, 255 +; CHECK-NEXT: lea %s2, 255 +; CHECK-NEXT: cmov.l.gt %s2, %s0, %s3 +; CHECK-NEXT: cmpu.l %s5, %s0, (56)0 +; CHECK-NEXT: cmov.l.gt %s4, %s0, %s5 +; CHECK-NEXT: cmov.l.eq %s2, %s4, %s3 +; CHECK-NEXT: maxs.l %s1, 0, %s1 +; CHECK-NEXT: or %s0, 0, %s2 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i128 @llvm.smax.i128(i128 %0, i128 255) + ret i128 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define signext i8 @func_smax_back_const_i8(i8 noundef signext %0) { +; CHECK-LABEL: func_smax_back_const_i8: +; CHECK: # %bb.0: +; CHECK-NEXT: maxs.w.sx %s0, -1, %s0 +; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i8 @llvm.smax.i8(i8 %0, i8 -1) + ret i8 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define signext i16 @func_smax_back_const_i16(i16 noundef signext %0) { +; CHECK-LABEL: func_smax_back_const_i16: +; CHECK: # %bb.0: +; CHECK-NEXT: maxs.w.sx %s0, %s0, (56)0 +; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i16 @llvm.smax.i16(i16 %0, i16 255) + ret i16 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define signext i32 @func_smax_back_const_i32(i32 noundef signext %0) { +; CHECK-LABEL: func_smax_back_const_i32: +; CHECK: # %bb.0: +; CHECK-NEXT: maxs.w.sx %s0, %s0, (56)0 +; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i32 @llvm.smax.i32(i32 %0, i32 255) + ret i32 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i64 @func_smax_back_const_i64(i64 noundef %0) { +; CHECK-LABEL: func_smax_back_const_i64: +; CHECK: # %bb.0: +; CHECK-NEXT: maxs.l %s0, %s0, (56)0 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i64 @llvm.smax.i64(i64 %0, i64 255) + ret i64 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i128 @func_smax_back_const_i128(i128 noundef %0) { +; CHECK-LABEL: func_smax_back_const_i128: +; CHECK: # %bb.0: +; CHECK-NEXT: cmps.l %s3, %s1, (0)1 +; CHECK-NEXT: lea %s4, 255 +; CHECK-NEXT: lea %s2, 255 +; CHECK-NEXT: cmov.l.gt %s2, %s0, %s3 +; CHECK-NEXT: cmpu.l %s5, %s0, (56)0 +; CHECK-NEXT: cmov.l.gt %s4, %s0, %s5 +; CHECK-NEXT: cmov.l.eq %s2, %s4, %s3 +; CHECK-NEXT: maxs.l %s1, 0, %s1 +; CHECK-NEXT: or %s0, 0, %s2 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i128 @llvm.smax.i128(i128 %0, i128 255) + ret i128 %2 +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i32 @llvm.smax.i32(i32, i32) + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i8 @llvm.smax.i8(i8, i8) + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i16 @llvm.smax.i16(i16, i16) + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i64 @llvm.smax.i64(i64, i64) + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i128 @llvm.smax.i128(i128, i128) diff --git a/llvm/test/CodeGen/VE/Scalar/smin.ll b/llvm/test/CodeGen/VE/Scalar/smin.ll new file mode 100644 index 0000000..a46c4e1 --- /dev/null +++ b/llvm/test/CodeGen/VE/Scalar/smin.ll @@ -0,0 +1,337 @@ +; RUN: llc < %s -mtriple=ve | FileCheck %s + +;;; Test ‘llvm.smin.*’ intrinsic +;;; +;;; Syntax: +;;; This is an overloaded intrinsic. You can use @llvm.smin on any +;;; integer bit width or any vector of integer elements. +;;; +;;; declare i32 @llvm.smin.i32(i32 %a, i32 %b) +;;; declare <4 x i32> @llvm.smin.v4i32(<4 x i32> %a, <4 x i32> %b) +;;; +;;; Overview: +;;; Return the smaller of %a and %b comparing the values as signed +;;; integers. Vector intrinsics operate on a per-element basis. +;;; The smaller element of %a and %b at a given index is returned +;;; for that index. +;;; +;;; Arguments: +;;; The arguments (%a and %b) may be of any integer type or a vector +;;; with integer element type. The argument types must match each +;;; other, and the return type must match the argument type. +;;; +;;; Note: +;;; We test only i8/i16/i32/i64/i128. + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define signext i8 @func_smin_var_i8(i8 noundef signext %0, i8 noundef signext %1) { +; CHECK-LABEL: func_smin_var_i8: +; CHECK: # %bb.0: +; CHECK-NEXT: mins.w.sx %s0, %s0, %s1 +; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %3 = tail call i8 @llvm.smin.i8(i8 %0, i8 %1) + ret i8 %3 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define signext i16 @func_smin_var_i16(i16 noundef signext %0, i16 noundef signext %1) { +; CHECK-LABEL: func_smin_var_i16: +; CHECK: # %bb.0: +; CHECK-NEXT: mins.w.sx %s0, %s0, %s1 +; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %3 = tail call i16 @llvm.smin.i16(i16 %0, i16 %1) + ret i16 %3 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define signext i32 @func_smin_var_i32(i32 noundef signext %0, i32 noundef signext %1) { +; CHECK-LABEL: func_smin_var_i32: +; CHECK: # %bb.0: +; CHECK-NEXT: mins.w.sx %s0, %s0, %s1 +; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %3 = tail call i32 @llvm.smin.i32(i32 %0, i32 %1) + ret i32 %3 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i64 @func_smin_var_i64(i64 noundef %0, i64 noundef %1) { +; CHECK-LABEL: func_smin_var_i64: +; CHECK: # %bb.0: +; CHECK-NEXT: mins.l %s0, %s0, %s1 +; CHECK-NEXT: b.l.t (, %s10) + %3 = tail call i64 @llvm.smin.i64(i64 %0, i64 %1) + ret i64 %3 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i128 @func_smin_var_i128(i128 noundef %0, i128 noundef %1) { +; CHECK-LABEL: func_smin_var_i128: +; CHECK: # %bb.0: +; CHECK-NEXT: cmps.l %s5, %s1, %s3 +; CHECK-NEXT: or %s4, 0, %s2 +; CHECK-NEXT: cmov.l.lt %s4, %s0, %s5 +; CHECK-NEXT: cmpu.l %s6, %s0, %s2 +; CHECK-NEXT: cmov.l.lt %s2, %s0, %s6 +; CHECK-NEXT: cmov.l.eq %s4, %s2, %s5 +; CHECK-NEXT: mins.l %s1, %s1, %s3 +; CHECK-NEXT: or %s0, 0, %s4 +; CHECK-NEXT: b.l.t (, %s10) + %3 = tail call i128 @llvm.smin.i128(i128 %0, i128 %1) + ret i128 %3 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define signext i8 @func_smin_fore_zero_i8(i8 noundef signext %0) { +; CHECK-LABEL: func_smin_fore_zero_i8: +; CHECK: # %bb.0: +; CHECK-NEXT: mins.w.sx %s0, 0, %s0 +; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i8 @llvm.smin.i8(i8 %0, i8 0) + ret i8 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define signext i16 @func_smin_fore_zero_i16(i16 noundef signext %0) { +; CHECK-LABEL: func_smin_fore_zero_i16: +; CHECK: # %bb.0: +; CHECK-NEXT: mins.w.sx %s0, 0, %s0 +; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i16 @llvm.smin.i16(i16 %0, i16 0) + ret i16 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define signext i32 @func_smin_fore_zero_i32(i32 noundef signext %0) { +; CHECK-LABEL: func_smin_fore_zero_i32: +; CHECK: # %bb.0: +; CHECK-NEXT: mins.w.sx %s0, 0, %s0 +; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i32 @llvm.smin.i32(i32 %0, i32 0) + ret i32 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i64 @func_smin_fore_zero_i64(i64 noundef %0) { +; CHECK-LABEL: func_smin_fore_zero_i64: +; CHECK: # %bb.0: +; CHECK-NEXT: mins.l %s0, 0, %s0 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i64 @llvm.smin.i64(i64 %0, i64 0) + ret i64 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i128 @func_smin_fore_zero_i128(i128 noundef %0) { +; CHECK-LABEL: func_smin_fore_zero_i128: +; CHECK: # %bb.0: +; CHECK-NEXT: or %s2, 0, (0)1 +; CHECK-NEXT: cmps.l %s3, %s1, (0)1 +; CHECK-NEXT: sra.l %s4, %s1, 63 +; CHECK-NEXT: and %s0, %s4, %s0 +; CHECK-NEXT: cmov.l.eq %s0, %s2, %s3 +; CHECK-NEXT: mins.l %s1, 0, %s1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i128 @llvm.smin.i128(i128 %0, i128 0) + ret i128 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define signext i8 @func_smin_back_zero_i8(i8 noundef signext %0) { +; CHECK-LABEL: func_smin_back_zero_i8: +; CHECK: # %bb.0: +; CHECK-NEXT: mins.w.sx %s0, 0, %s0 +; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i8 @llvm.smin.i8(i8 %0, i8 0) + ret i8 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define signext i16 @func_smin_back_zero_i16(i16 noundef signext %0) { +; CHECK-LABEL: func_smin_back_zero_i16: +; CHECK: # %bb.0: +; CHECK-NEXT: mins.w.sx %s0, 0, %s0 +; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i16 @llvm.smin.i16(i16 %0, i16 0) + ret i16 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define signext i32 @func_smin_back_zero_i32(i32 noundef signext %0) { +; CHECK-LABEL: func_smin_back_zero_i32: +; CHECK: # %bb.0: +; CHECK-NEXT: mins.w.sx %s0, 0, %s0 +; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i32 @llvm.smin.i32(i32 %0, i32 0) + ret i32 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i64 @func_smin_back_zero_i64(i64 noundef %0) { +; CHECK-LABEL: func_smin_back_zero_i64: +; CHECK: # %bb.0: +; CHECK-NEXT: mins.l %s0, 0, %s0 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i64 @llvm.smin.i64(i64 %0, i64 0) + ret i64 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i128 @func_smin_back_zero_i128(i128 noundef %0) { +; CHECK-LABEL: func_smin_back_zero_i128: +; CHECK: # %bb.0: +; CHECK-NEXT: or %s2, 0, (0)1 +; CHECK-NEXT: cmps.l %s3, %s1, (0)1 +; CHECK-NEXT: sra.l %s4, %s1, 63 +; CHECK-NEXT: and %s0, %s4, %s0 +; CHECK-NEXT: cmov.l.eq %s0, %s2, %s3 +; CHECK-NEXT: mins.l %s1, 0, %s1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i128 @llvm.smin.i128(i128 %0, i128 0) + ret i128 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define signext i8 @func_smin_fore_const_i8(i8 noundef signext %0) { +; CHECK-LABEL: func_smin_fore_const_i8: +; CHECK: # %bb.0: +; CHECK-NEXT: mins.w.sx %s0, -1, %s0 +; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i8 @llvm.smin.i8(i8 %0, i8 -1) + ret i8 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define signext i16 @func_smin_fore_const_i16(i16 noundef signext %0) { +; CHECK-LABEL: func_smin_fore_const_i16: +; CHECK: # %bb.0: +; CHECK-NEXT: mins.w.sx %s0, %s0, (56)0 +; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i16 @llvm.smin.i16(i16 %0, i16 255) + ret i16 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define signext i32 @func_smin_fore_const_i32(i32 noundef signext %0) { +; CHECK-LABEL: func_smin_fore_const_i32: +; CHECK: # %bb.0: +; CHECK-NEXT: mins.w.sx %s0, %s0, (56)0 +; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i32 @llvm.smin.i32(i32 %0, i32 255) + ret i32 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i64 @func_smin_fore_const_i64(i64 noundef %0) { +; CHECK-LABEL: func_smin_fore_const_i64: +; CHECK: # %bb.0: +; CHECK-NEXT: mins.l %s0, %s0, (56)0 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i64 @llvm.smin.i64(i64 %0, i64 255) + ret i64 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i128 @func_smin_fore_const_i128(i128 noundef %0) { +; CHECK-LABEL: func_smin_fore_const_i128: +; CHECK: # %bb.0: +; CHECK-NEXT: cmps.l %s3, %s1, (0)1 +; CHECK-NEXT: lea %s4, 255 +; CHECK-NEXT: lea %s2, 255 +; CHECK-NEXT: cmov.l.lt %s2, %s0, %s3 +; CHECK-NEXT: cmpu.l %s5, %s0, (56)0 +; CHECK-NEXT: cmov.l.lt %s4, %s0, %s5 +; CHECK-NEXT: cmov.l.eq %s2, %s4, %s3 +; CHECK-NEXT: mins.l %s1, 0, %s1 +; CHECK-NEXT: or %s0, 0, %s2 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i128 @llvm.smin.i128(i128 %0, i128 255) + ret i128 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define signext i8 @func_smin_back_const_i8(i8 noundef signext %0) { +; CHECK-LABEL: func_smin_back_const_i8: +; CHECK: # %bb.0: +; CHECK-NEXT: mins.w.sx %s0, -1, %s0 +; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i8 @llvm.smin.i8(i8 %0, i8 -1) + ret i8 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define signext i16 @func_smin_back_const_i16(i16 noundef signext %0) { +; CHECK-LABEL: func_smin_back_const_i16: +; CHECK: # %bb.0: +; CHECK-NEXT: mins.w.sx %s0, %s0, (56)0 +; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i16 @llvm.smin.i16(i16 %0, i16 255) + ret i16 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define signext i32 @func_smin_back_const_i32(i32 noundef signext %0) { +; CHECK-LABEL: func_smin_back_const_i32: +; CHECK: # %bb.0: +; CHECK-NEXT: mins.w.sx %s0, %s0, (56)0 +; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i32 @llvm.smin.i32(i32 %0, i32 255) + ret i32 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i64 @func_smin_back_const_i64(i64 noundef %0) { +; CHECK-LABEL: func_smin_back_const_i64: +; CHECK: # %bb.0: +; CHECK-NEXT: mins.l %s0, %s0, (56)0 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i64 @llvm.smin.i64(i64 %0, i64 255) + ret i64 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i128 @func_smin_back_const_i128(i128 noundef %0) { +; CHECK-LABEL: func_smin_back_const_i128: +; CHECK: # %bb.0: +; CHECK-NEXT: cmps.l %s3, %s1, (0)1 +; CHECK-NEXT: lea %s4, 255 +; CHECK-NEXT: lea %s2, 255 +; CHECK-NEXT: cmov.l.lt %s2, %s0, %s3 +; CHECK-NEXT: cmpu.l %s5, %s0, (56)0 +; CHECK-NEXT: cmov.l.lt %s4, %s0, %s5 +; CHECK-NEXT: cmov.l.eq %s2, %s4, %s3 +; CHECK-NEXT: mins.l %s1, 0, %s1 +; CHECK-NEXT: or %s0, 0, %s2 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i128 @llvm.smin.i128(i128 %0, i128 255) + ret i128 %2 +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i32 @llvm.smin.i32(i32, i32) + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i8 @llvm.smin.i8(i8, i8) + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i16 @llvm.smin.i16(i16, i16) + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i64 @llvm.smin.i64(i64, i64) + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i128 @llvm.smin.i128(i128, i128) diff --git a/llvm/test/CodeGen/VE/Scalar/umax.ll b/llvm/test/CodeGen/VE/Scalar/umax.ll new file mode 100644 index 0000000..3df721f --- /dev/null +++ b/llvm/test/CodeGen/VE/Scalar/umax.ll @@ -0,0 +1,358 @@ +; RUN: llc < %s -mtriple=ve | FileCheck %s + +;;; Test ‘llvm.umax.*’ intrinsic +;;; +;;; Syntax: +;;; This is an overloaded intrinsic. You can use @llvm.umax on any +;;; integer bit width or any vector of integer elements. +;;; +;;; declare i32 @llvm.umax.i32(i32 %a, i32 %b) +;;; declare <4 x i32> @llvm.umax.v4i32(<4 x i32> %a, <4 x i32> %b) +;;; +;;; Overview: +;;; Return the larger of %a and %b comparing the values as unsigned +;;; integers. Vector intrinsics operate on a per-element basis. The +;;; larger element of %a and %b at a given index is returned for +;;; that index. +;;; +;;; Arguments: +;;; The arguments (%a and %b) may be of any integer type or a vector +;;; with integer element type. The argument types must match each +;;; other, and the return type must match the argument type. +;;; +;;; Note: +;;; We test only i1/u8/u16/u32/u64/u128. + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define zeroext i1 @func_umax_var_i1(i1 noundef zeroext %0, i1 noundef zeroext %1) { +; CHECK-LABEL: func_umax_var_i1: +; CHECK: # %bb.0: +; CHECK-NEXT: maxs.w.sx %s0, %s0, %s1 +; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %3 = tail call i1 @llvm.umax.i1(i1 %0, i1 %1) + ret i1 %3 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define zeroext i8 @func_umax_var_u8(i8 noundef zeroext %0, i8 noundef zeroext %1) { +; CHECK-LABEL: func_umax_var_u8: +; CHECK: # %bb.0: +; CHECK-NEXT: maxs.w.sx %s0, %s0, %s1 +; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %3 = tail call i8 @llvm.umax.i8(i8 %0, i8 %1) + ret i8 %3 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define zeroext i16 @func_umax_var_u16(i16 noundef zeroext %0, i16 noundef zeroext %1) { +; CHECK-LABEL: func_umax_var_u16: +; CHECK: # %bb.0: +; CHECK-NEXT: maxs.w.sx %s0, %s0, %s1 +; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %3 = tail call i16 @llvm.umax.i16(i16 %0, i16 %1) + ret i16 %3 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define zeroext i32 @func_umax_var_u32(i32 noundef zeroext %0, i32 noundef zeroext %1) { +; CHECK-LABEL: func_umax_var_u32: +; CHECK: # %bb.0: +; CHECK-NEXT: cmpu.w %s2, %s0, %s1 +; CHECK-NEXT: cmov.w.gt %s1, %s0, %s2 +; CHECK-NEXT: adds.w.zx %s0, %s1, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %3 = tail call i32 @llvm.umax.i32(i32 %0, i32 %1) + ret i32 %3 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i64 @func_umax_var_u64(i64 noundef %0, i64 noundef %1) { +; CHECK-LABEL: func_umax_var_u64: +; CHECK: # %bb.0: +; CHECK-NEXT: cmpu.l %s2, %s0, %s1 +; CHECK-NEXT: cmov.l.gt %s1, %s0, %s2 +; CHECK-NEXT: or %s0, 0, %s1 +; CHECK-NEXT: b.l.t (, %s10) + %3 = tail call i64 @llvm.umax.i64(i64 %0, i64 %1) + ret i64 %3 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i128 @func_umax_var_u128(i128 noundef %0, i128 noundef %1) { +; CHECK-LABEL: func_umax_var_u128: +; CHECK: # %bb.0: +; CHECK-NEXT: cmpu.l %s5, %s1, %s3 +; CHECK-NEXT: or %s4, 0, %s2 +; CHECK-NEXT: cmov.l.gt %s4, %s0, %s5 +; CHECK-NEXT: cmpu.l %s6, %s0, %s2 +; CHECK-NEXT: cmov.l.gt %s2, %s0, %s6 +; CHECK-NEXT: cmps.l %s0, %s1, %s3 +; CHECK-NEXT: cmov.l.eq %s4, %s2, %s0 +; CHECK-NEXT: cmov.l.gt %s3, %s1, %s5 +; CHECK-NEXT: or %s0, 0, %s4 +; CHECK-NEXT: or %s1, 0, %s3 +; CHECK-NEXT: b.l.t (, %s10) + %3 = tail call i128 @llvm.umax.i128(i128 %0, i128 %1) + ret i128 %3 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define zeroext i1 @func_umax_fore_zero_i1(i1 noundef returned zeroext %0) { +; CHECK-LABEL: func_umax_fore_zero_i1: +; CHECK: # %bb.0: +; CHECK-NEXT: b.l.t (, %s10) + ret i1 %0 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define zeroext i8 @func_umax_fore_zero_u8(i8 noundef returned zeroext %0) { +; CHECK-LABEL: func_umax_fore_zero_u8: +; CHECK: # %bb.0: +; CHECK-NEXT: b.l.t (, %s10) + ret i8 %0 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define zeroext i16 @func_umax_fore_zero_u16(i16 noundef returned zeroext %0) { +; CHECK-LABEL: func_umax_fore_zero_u16: +; CHECK: # %bb.0: +; CHECK-NEXT: b.l.t (, %s10) + ret i16 %0 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define zeroext i32 @func_umax_fore_zero_u32(i32 noundef returned zeroext %0) { +; CHECK-LABEL: func_umax_fore_zero_u32: +; CHECK: # %bb.0: +; CHECK-NEXT: b.l.t (, %s10) + ret i32 %0 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define i64 @func_umax_fore_zero_u64(i64 noundef returned %0) { +; CHECK-LABEL: func_umax_fore_zero_u64: +; CHECK: # %bb.0: +; CHECK-NEXT: b.l.t (, %s10) + ret i64 %0 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define i128 @func_umax_fore_zero_u128(i128 noundef returned %0) { +; CHECK-LABEL: func_umax_fore_zero_u128: +; CHECK: # %bb.0: +; CHECK-NEXT: b.l.t (, %s10) + ret i128 %0 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define zeroext i1 @func_umax_back_zero_i1(i1 noundef returned zeroext %0) { +; CHECK-LABEL: func_umax_back_zero_i1: +; CHECK: # %bb.0: +; CHECK-NEXT: b.l.t (, %s10) + ret i1 %0 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define zeroext i8 @func_umax_back_zero_u8(i8 noundef returned zeroext %0) { +; CHECK-LABEL: func_umax_back_zero_u8: +; CHECK: # %bb.0: +; CHECK-NEXT: b.l.t (, %s10) + ret i8 %0 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define zeroext i16 @func_umax_back_zero_u16(i16 noundef returned zeroext %0) { +; CHECK-LABEL: func_umax_back_zero_u16: +; CHECK: # %bb.0: +; CHECK-NEXT: b.l.t (, %s10) + ret i16 %0 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define zeroext i32 @func_umax_back_zero_u32(i32 noundef returned zeroext %0) { +; CHECK-LABEL: func_umax_back_zero_u32: +; CHECK: # %bb.0: +; CHECK-NEXT: b.l.t (, %s10) + ret i32 %0 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define i64 @func_umax_back_zero_u64(i64 noundef returned %0) { +; CHECK-LABEL: func_umax_back_zero_u64: +; CHECK: # %bb.0: +; CHECK-NEXT: b.l.t (, %s10) + ret i64 %0 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define i128 @func_umax_back_zero_u128(i128 noundef returned %0) { +; CHECK-LABEL: func_umax_back_zero_u128: +; CHECK: # %bb.0: +; CHECK-NEXT: b.l.t (, %s10) + ret i128 %0 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define zeroext i1 @func_umax_fore_const_i1(i1 noundef zeroext %0) { +; CHECK-LABEL: func_umax_fore_const_i1: +; CHECK: # %bb.0: +; CHECK-NEXT: or %s0, 1, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + ret i1 true +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define zeroext i8 @func_umax_fore_const_u8(i8 noundef zeroext %0) { +; CHECK-LABEL: func_umax_fore_const_u8: +; CHECK: # %bb.0: +; CHECK-NEXT: lea %s0, 255 +; CHECK-NEXT: b.l.t (, %s10) + ret i8 -1 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define zeroext i16 @func_umax_fore_const_u16(i16 noundef zeroext %0) { +; CHECK-LABEL: func_umax_fore_const_u16: +; CHECK: # %bb.0: +; CHECK-NEXT: maxs.w.sx %s0, %s0, (56)0 +; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i16 @llvm.umax.i16(i16 %0, i16 255) + ret i16 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define zeroext i32 @func_umax_fore_const_u32(i32 noundef zeroext %0) { +; CHECK-LABEL: func_umax_fore_const_u32: +; CHECK: # %bb.0: +; CHECK-NEXT: lea %s1, 255 +; CHECK-NEXT: cmpu.w %s2, %s0, %s1 +; CHECK-NEXT: cmov.w.gt %s1, %s0, %s2 +; CHECK-NEXT: adds.w.zx %s0, %s1, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i32 @llvm.umax.i32(i32 %0, i32 255) + ret i32 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i64 @func_umax_fore_const_u64(i64 noundef %0) { +; CHECK-LABEL: func_umax_fore_const_u64: +; CHECK: # %bb.0: +; CHECK-NEXT: lea %s1, 255 +; CHECK-NEXT: cmpu.l %s2, %s0, (56)0 +; CHECK-NEXT: cmov.l.gt %s1, %s0, %s2 +; CHECK-NEXT: or %s0, 0, %s1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i64 @llvm.umax.i64(i64 %0, i64 255) + ret i64 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i128 @func_umax_fore_const_u128(i128 noundef %0) { +; CHECK-LABEL: func_umax_fore_const_u128: +; CHECK: # %bb.0: +; CHECK-NEXT: cmps.l %s3, %s1, (0)1 +; CHECK-NEXT: lea %s4, 255 +; CHECK-NEXT: lea %s2, 255 +; CHECK-NEXT: cmov.l.ne %s2, %s0, %s3 +; CHECK-NEXT: cmpu.l %s5, %s0, (56)0 +; CHECK-NEXT: cmov.l.gt %s4, %s0, %s5 +; CHECK-NEXT: cmov.l.eq %s2, %s4, %s3 +; CHECK-NEXT: or %s0, 0, %s2 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i128 @llvm.umax.i128(i128 %0, i128 255) + ret i128 %2 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define zeroext i1 @func_umax_back_const_i1(i1 noundef zeroext %0) { +; CHECK-LABEL: func_umax_back_const_i1: +; CHECK: # %bb.0: +; CHECK-NEXT: or %s0, 1, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + ret i1 true +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define zeroext i8 @func_umax_back_const_u8(i8 noundef zeroext %0) { +; CHECK-LABEL: func_umax_back_const_u8: +; CHECK: # %bb.0: +; CHECK-NEXT: lea %s0, 255 +; CHECK-NEXT: b.l.t (, %s10) + ret i8 -1 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define zeroext i16 @func_umax_back_const_u16(i16 noundef zeroext %0) { +; CHECK-LABEL: func_umax_back_const_u16: +; CHECK: # %bb.0: +; CHECK-NEXT: maxs.w.sx %s0, %s0, (56)0 +; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i16 @llvm.umax.i16(i16 %0, i16 255) + ret i16 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define zeroext i32 @func_umax_back_const_u32(i32 noundef zeroext %0) { +; CHECK-LABEL: func_umax_back_const_u32: +; CHECK: # %bb.0: +; CHECK-NEXT: lea %s1, 255 +; CHECK-NEXT: cmpu.w %s2, %s0, %s1 +; CHECK-NEXT: cmov.w.gt %s1, %s0, %s2 +; CHECK-NEXT: adds.w.zx %s0, %s1, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i32 @llvm.umax.i32(i32 %0, i32 255) + ret i32 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i64 @func_umax_back_const_u64(i64 noundef %0) { +; CHECK-LABEL: func_umax_back_const_u64: +; CHECK: # %bb.0: +; CHECK-NEXT: lea %s1, 255 +; CHECK-NEXT: cmpu.l %s2, %s0, (56)0 +; CHECK-NEXT: cmov.l.gt %s1, %s0, %s2 +; CHECK-NEXT: or %s0, 0, %s1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i64 @llvm.umax.i64(i64 %0, i64 255) + ret i64 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i128 @func_umax_back_const_u128(i128 noundef %0) { +; CHECK-LABEL: func_umax_back_const_u128: +; CHECK: # %bb.0: +; CHECK-NEXT: cmps.l %s3, %s1, (0)1 +; CHECK-NEXT: lea %s4, 255 +; CHECK-NEXT: lea %s2, 255 +; CHECK-NEXT: cmov.l.ne %s2, %s0, %s3 +; CHECK-NEXT: cmpu.l %s5, %s0, (56)0 +; CHECK-NEXT: cmov.l.gt %s4, %s0, %s5 +; CHECK-NEXT: cmov.l.eq %s2, %s4, %s3 +; CHECK-NEXT: or %s0, 0, %s2 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i128 @llvm.umax.i128(i128 %0, i128 255) + ret i128 %2 +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i32 @llvm.umax.i32(i32, i32) + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i1 @llvm.umax.i1(i1, i1) + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i8 @llvm.umax.i8(i8, i8) + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i16 @llvm.umax.i16(i16, i16) + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i64 @llvm.umax.i64(i64, i64) + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i128 @llvm.umax.i128(i128, i128) diff --git a/llvm/test/CodeGen/VE/Scalar/umin.ll b/llvm/test/CodeGen/VE/Scalar/umin.ll new file mode 100644 index 0000000..937fa42 --- /dev/null +++ b/llvm/test/CodeGen/VE/Scalar/umin.ll @@ -0,0 +1,368 @@ +; RUN: llc < %s -mtriple=ve | FileCheck %s + +;;; Test ‘llvm.umin.*’ intrinsic +;;; +;;; Syntax: +;;; This is an overloaded intrinsic. You can use @llvm.umin on any +;;; integer bit width or any vector of integer elements. +;;; +;;; declare i32 @llvm.umin.i32(i32 %a, i32 %b) +;;; declare <4 x i32> @llvm.umin.v4i32(<4 x i32> %a, <4 x i32> %b) +;;; +;;; Overview: +;;; Return the smaller of %a and %b comparing the values as unsigned +;;; integers. Vector intrinsics operate on a per-element basis. The +;;; smaller element of %a and %b at a given index is returned for +;;; that index. +;;; +;;; Arguments: +;;; The arguments (%a and %b) may be of any integer type or a vector +;;; with integer element type. The argument types must match each +;;; other, and the return type must match the argument type. +;;; +;;; Note: +;;; We test only i1/u8/u16/u32/u64/u128. + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define zeroext i1 @func_umin_var_i1(i1 noundef zeroext %0, i1 noundef zeroext %1) { +; CHECK-LABEL: func_umin_var_i1: +; CHECK: # %bb.0: +; CHECK-NEXT: mins.w.sx %s0, %s0, %s1 +; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %3 = tail call i1 @llvm.umin.i1(i1 %0, i1 %1) + ret i1 %3 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define zeroext i8 @func_umin_var_u8(i8 noundef zeroext %0, i8 noundef zeroext %1) { +; CHECK-LABEL: func_umin_var_u8: +; CHECK: # %bb.0: +; CHECK-NEXT: mins.w.sx %s0, %s0, %s1 +; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %3 = tail call i8 @llvm.umin.i8(i8 %0, i8 %1) + ret i8 %3 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define zeroext i16 @func_umin_var_u16(i16 noundef zeroext %0, i16 noundef zeroext %1) { +; CHECK-LABEL: func_umin_var_u16: +; CHECK: # %bb.0: +; CHECK-NEXT: mins.w.sx %s0, %s0, %s1 +; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %3 = tail call i16 @llvm.umin.i16(i16 %0, i16 %1) + ret i16 %3 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define zeroext i32 @func_umin_var_u32(i32 noundef zeroext %0, i32 noundef zeroext %1) { +; CHECK-LABEL: func_umin_var_u32: +; CHECK: # %bb.0: +; CHECK-NEXT: cmpu.w %s2, %s0, %s1 +; CHECK-NEXT: cmov.w.lt %s1, %s0, %s2 +; CHECK-NEXT: adds.w.zx %s0, %s1, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %3 = tail call i32 @llvm.umin.i32(i32 %0, i32 %1) + ret i32 %3 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i64 @func_umin_var_u64(i64 noundef %0, i64 noundef %1) { +; CHECK-LABEL: func_umin_var_u64: +; CHECK: # %bb.0: +; CHECK-NEXT: cmpu.l %s2, %s0, %s1 +; CHECK-NEXT: cmov.l.lt %s1, %s0, %s2 +; CHECK-NEXT: or %s0, 0, %s1 +; CHECK-NEXT: b.l.t (, %s10) + %3 = tail call i64 @llvm.umin.i64(i64 %0, i64 %1) + ret i64 %3 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i128 @func_umin_var_u128(i128 noundef %0, i128 noundef %1) { +; CHECK-LABEL: func_umin_var_u128: +; CHECK: # %bb.0: +; CHECK-NEXT: cmpu.l %s5, %s1, %s3 +; CHECK-NEXT: or %s4, 0, %s2 +; CHECK-NEXT: cmov.l.lt %s4, %s0, %s5 +; CHECK-NEXT: cmpu.l %s6, %s0, %s2 +; CHECK-NEXT: cmov.l.lt %s2, %s0, %s6 +; CHECK-NEXT: cmps.l %s0, %s1, %s3 +; CHECK-NEXT: cmov.l.eq %s4, %s2, %s0 +; CHECK-NEXT: cmov.l.lt %s3, %s1, %s5 +; CHECK-NEXT: or %s0, 0, %s4 +; CHECK-NEXT: or %s1, 0, %s3 +; CHECK-NEXT: b.l.t (, %s10) + %3 = tail call i128 @llvm.umin.i128(i128 %0, i128 %1) + ret i128 %3 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define zeroext i1 @func_umin_fore_zero_i1(i1 noundef zeroext %0) { +; CHECK-LABEL: func_umin_fore_zero_i1: +; CHECK: # %bb.0: +; CHECK-NEXT: or %s0, 0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + ret i1 false +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define zeroext i8 @func_umin_fore_zero_u8(i8 noundef zeroext %0) { +; CHECK-LABEL: func_umin_fore_zero_u8: +; CHECK: # %bb.0: +; CHECK-NEXT: or %s0, 0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + ret i8 0 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define zeroext i16 @func_umin_fore_zero_u16(i16 noundef zeroext %0) { +; CHECK-LABEL: func_umin_fore_zero_u16: +; CHECK: # %bb.0: +; CHECK-NEXT: or %s0, 0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + ret i16 0 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define zeroext i32 @func_umin_fore_zero_u32(i32 noundef zeroext %0) { +; CHECK-LABEL: func_umin_fore_zero_u32: +; CHECK: # %bb.0: +; CHECK-NEXT: or %s0, 0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + ret i32 0 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define i64 @func_umin_fore_zero_u64(i64 noundef %0) { +; CHECK-LABEL: func_umin_fore_zero_u64: +; CHECK: # %bb.0: +; CHECK-NEXT: or %s0, 0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + ret i64 0 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define i128 @func_umin_fore_zero_u128(i128 noundef %0) { +; CHECK-LABEL: func_umin_fore_zero_u128: +; CHECK: # %bb.0: +; CHECK-NEXT: or %s0, 0, (0)1 +; CHECK-NEXT: or %s1, 0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + ret i128 0 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define zeroext i1 @func_umin_back_zero_i1(i1 noundef zeroext %0) { +; CHECK-LABEL: func_umin_back_zero_i1: +; CHECK: # %bb.0: +; CHECK-NEXT: or %s0, 0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + ret i1 false +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define zeroext i8 @func_umin_back_zero_u8(i8 noundef zeroext %0) { +; CHECK-LABEL: func_umin_back_zero_u8: +; CHECK: # %bb.0: +; CHECK-NEXT: or %s0, 0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + ret i8 0 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define zeroext i16 @func_umin_back_zero_u16(i16 noundef zeroext %0) { +; CHECK-LABEL: func_umin_back_zero_u16: +; CHECK: # %bb.0: +; CHECK-NEXT: or %s0, 0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + ret i16 0 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define zeroext i32 @func_umin_back_zero_u32(i32 noundef zeroext %0) { +; CHECK-LABEL: func_umin_back_zero_u32: +; CHECK: # %bb.0: +; CHECK-NEXT: or %s0, 0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + ret i32 0 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define i64 @func_umin_back_zero_u64(i64 noundef %0) { +; CHECK-LABEL: func_umin_back_zero_u64: +; CHECK: # %bb.0: +; CHECK-NEXT: or %s0, 0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + ret i64 0 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define i128 @func_umin_back_zero_u128(i128 noundef %0) { +; CHECK-LABEL: func_umin_back_zero_u128: +; CHECK: # %bb.0: +; CHECK-NEXT: or %s0, 0, (0)1 +; CHECK-NEXT: or %s1, 0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + ret i128 0 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define zeroext i1 @func_umin_fore_const_i1(i1 noundef returned zeroext %0) { +; CHECK-LABEL: func_umin_fore_const_i1: +; CHECK: # %bb.0: +; CHECK-NEXT: b.l.t (, %s10) + ret i1 %0 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define zeroext i8 @func_umin_fore_const_u8(i8 noundef returned zeroext %0) { +; CHECK-LABEL: func_umin_fore_const_u8: +; CHECK: # %bb.0: +; CHECK-NEXT: b.l.t (, %s10) + ret i8 %0 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define zeroext i16 @func_umin_fore_const_u16(i16 noundef zeroext %0) { +; CHECK-LABEL: func_umin_fore_const_u16: +; CHECK: # %bb.0: +; CHECK-NEXT: mins.w.sx %s0, %s0, (56)0 +; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i16 @llvm.umin.i16(i16 %0, i16 255) + ret i16 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define zeroext i32 @func_umin_fore_const_u32(i32 noundef zeroext %0) { +; CHECK-LABEL: func_umin_fore_const_u32: +; CHECK: # %bb.0: +; CHECK-NEXT: lea %s1, 255 +; CHECK-NEXT: cmpu.w %s2, %s0, %s1 +; CHECK-NEXT: cmov.w.lt %s1, %s0, %s2 +; CHECK-NEXT: adds.w.zx %s0, %s1, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i32 @llvm.umin.i32(i32 %0, i32 255) + ret i32 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i64 @func_umin_fore_const_u64(i64 noundef %0) { +; CHECK-LABEL: func_umin_fore_const_u64: +; CHECK: # %bb.0: +; CHECK-NEXT: lea %s1, 255 +; CHECK-NEXT: cmpu.l %s2, %s0, (56)0 +; CHECK-NEXT: cmov.l.lt %s1, %s0, %s2 +; CHECK-NEXT: or %s0, 0, %s1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i64 @llvm.umin.i64(i64 %0, i64 255) + ret i64 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i128 @func_umin_fore_const_u128(i128 noundef %0) { +; CHECK-LABEL: func_umin_fore_const_u128: +; CHECK: # %bb.0: +; CHECK-NEXT: lea %s2, 255 +; CHECK-NEXT: cmpu.l %s3, %s0, (56)0 +; CHECK-NEXT: lea %s4, 255 +; CHECK-NEXT: cmov.l.lt %s4, %s0, %s3 +; CHECK-NEXT: cmps.l %s0, %s1, (0)1 +; CHECK-NEXT: cmov.l.eq %s2, %s4, %s0 +; CHECK-NEXT: or %s1, 0, (0)1 +; CHECK-NEXT: or %s0, 0, %s2 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i128 @llvm.umin.i128(i128 %0, i128 255) + ret i128 %2 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define zeroext i1 @func_umin_back_const_i1(i1 noundef returned zeroext %0) { +; CHECK-LABEL: func_umin_back_const_i1: +; CHECK: # %bb.0: +; CHECK-NEXT: b.l.t (, %s10) + ret i1 %0 +} + +; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +define zeroext i8 @func_umin_back_const_u8(i8 noundef returned zeroext %0) { +; CHECK-LABEL: func_umin_back_const_u8: +; CHECK: # %bb.0: +; CHECK-NEXT: b.l.t (, %s10) + ret i8 %0 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define zeroext i16 @func_umin_back_const_u16(i16 noundef zeroext %0) { +; CHECK-LABEL: func_umin_back_const_u16: +; CHECK: # %bb.0: +; CHECK-NEXT: mins.w.sx %s0, %s0, (56)0 +; CHECK-NEXT: adds.w.zx %s0, %s0, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i16 @llvm.umin.i16(i16 %0, i16 255) + ret i16 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define zeroext i32 @func_umin_back_const_u32(i32 noundef zeroext %0) { +; CHECK-LABEL: func_umin_back_const_u32: +; CHECK: # %bb.0: +; CHECK-NEXT: lea %s1, 255 +; CHECK-NEXT: cmpu.w %s2, %s0, %s1 +; CHECK-NEXT: cmov.w.lt %s1, %s0, %s2 +; CHECK-NEXT: adds.w.zx %s0, %s1, (0)1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i32 @llvm.umin.i32(i32 %0, i32 255) + ret i32 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i64 @func_umin_back_const_u64(i64 noundef %0) { +; CHECK-LABEL: func_umin_back_const_u64: +; CHECK: # %bb.0: +; CHECK-NEXT: lea %s1, 255 +; CHECK-NEXT: cmpu.l %s2, %s0, (56)0 +; CHECK-NEXT: cmov.l.lt %s1, %s0, %s2 +; CHECK-NEXT: or %s0, 0, %s1 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i64 @llvm.umin.i64(i64 %0, i64 255) + ret i64 %2 +} + +; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +define i128 @func_umin_back_const_u128(i128 noundef %0) { +; CHECK-LABEL: func_umin_back_const_u128: +; CHECK: # %bb.0: +; CHECK-NEXT: lea %s2, 255 +; CHECK-NEXT: cmpu.l %s3, %s0, (56)0 +; CHECK-NEXT: lea %s4, 255 +; CHECK-NEXT: cmov.l.lt %s4, %s0, %s3 +; CHECK-NEXT: cmps.l %s0, %s1, (0)1 +; CHECK-NEXT: cmov.l.eq %s2, %s4, %s0 +; CHECK-NEXT: or %s1, 0, (0)1 +; CHECK-NEXT: or %s0, 0, %s2 +; CHECK-NEXT: b.l.t (, %s10) + %2 = tail call i128 @llvm.umin.i128(i128 %0, i128 255) + ret i128 %2 +} + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i32 @llvm.umin.i32(i32, i32) + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i1 @llvm.umin.i1(i1, i1) + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i8 @llvm.umin.i8(i8, i8) + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i16 @llvm.umin.i16(i16, i16) + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i64 @llvm.umin.i64(i64, i64) + +; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn +declare i128 @llvm.umin.i128(i128, i128) -- 2.7.4