1; RUN: llc < %s -mtriple=ve | FileCheck %s 2 3;;; Test ‘llvm.maxnum.*’ intrinsic 4;;; 5;;; Syntax: 6;;; This is an overloaded intrinsic. You can use llvm.maxnum on any 7;;; floating-point or vector of floating-point type. Not all targets 8;;; support all types however. 9;;; 10;;; declare float @llvm.maxnum.f32(float %Val0, float %Val1) 11;;; declare double @llvm.maxnum.f64(double %Val0, double %Val1) 12;;; declare x86_fp80 @llvm.maxnum.f80(x86_fp80 %Val0, x86_fp80 %Val1) 13;;; declare fp128 @llvm.maxnum.f128(fp128 %Val0, fp128 %Val1) 14;;; declare ppc_fp128 @llvm.maxnum.ppcf128(ppc_fp128 %Val0, ppc_fp128 %Val1) 15;;; 16;;; Overview: 17;;; The ‘llvm.maxnum.*’ intrinsics return the maximum of the two arguments. 18;;; 19;;; Arguments: 20;;; The arguments and return value are floating-point numbers of the same 21;;; type. 22;;; 23;;; Semantics: 24;;; Follows the IEEE-754 semantics for maxNum except for the handling of 25;;; signaling NaNs. This matches the behavior of libm’s fmax. 26;;; 27;;; If either operand is a NaN, returns the other non-NaN operand. 28;;; Returns NaN only if both operands are NaN. The returned NaN is 29;;; always quiet. If the operands compare equal, returns a value 30;;; that compares equal to both operands. This means that 31;;; fmax(+/-0.0, +/-0.0) could return either -0.0 or 0.0. 32;;; 33;;; Unlike the IEEE-754 2008 behavior, this does not distinguish between 34;;; signaling and quiet NaN inputs. If a target’s implementation follows 35;;; the standard and returns a quiet NaN if either input is a signaling 36;;; NaN, the intrinsic lowering is responsible for quieting the inputs 37;;; to correctly return the non-NaN input (e.g. by using the equivalent 38;;; of llvm.canonicalize). 39;;; 40;;; Note: 41;;; We test only float/double/fp128. 42 43; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn 44define float @func_fp_fmax_var_float(float noundef %0, float noundef %1) { 45; CHECK-LABEL: func_fp_fmax_var_float: 46; CHECK: # %bb.0: 47; CHECK-NEXT: fmax.s %s0, %s0, %s1 48; CHECK-NEXT: b.l.t (, %s10) 49 %3 = tail call fast float @llvm.maxnum.f32(float %0, float %1) 50 ret float %3 51} 52 53; Function Attrs: mustprogress nocallback nofree nosync nounwind readnone speculatable willreturn 54declare float @llvm.maxnum.f32(float, float) 55 56; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn 57define double @func_fp_fmax_var_double(double noundef %0, double noundef %1) { 58; CHECK-LABEL: func_fp_fmax_var_double: 59; CHECK: # %bb.0: 60; CHECK-NEXT: fmax.d %s0, %s0, %s1 61; CHECK-NEXT: b.l.t (, %s10) 62 %3 = tail call fast double @llvm.maxnum.f64(double %0, double %1) 63 ret double %3 64} 65 66; Function Attrs: mustprogress nocallback nofree nosync nounwind readnone speculatable willreturn 67declare double @llvm.maxnum.f64(double, double) 68 69; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn 70define fp128 @func_fp_fmax_var_quad(fp128 noundef %0, fp128 noundef %1) { 71; CHECK-LABEL: func_fp_fmax_var_quad: 72; CHECK: # %bb.0: 73; CHECK-NEXT: fcmp.q %s4, %s0, %s2 74; CHECK-NEXT: cmov.d.gt %s2, %s0, %s4 75; CHECK-NEXT: cmov.d.gt %s3, %s1, %s4 76; CHECK-NEXT: or %s0, 0, %s2 77; CHECK-NEXT: or %s1, 0, %s3 78; CHECK-NEXT: b.l.t (, %s10) 79 %3 = tail call fast fp128 @llvm.maxnum.f128(fp128 %0, fp128 %1) 80 ret fp128 %3 81} 82 83; Function Attrs: mustprogress nocallback nofree nosync nounwind readnone speculatable willreturn 84declare fp128 @llvm.maxnum.f128(fp128, fp128) 85 86; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn 87define float @func_fp_fmax_zero_float(float noundef %0) { 88; CHECK-LABEL: func_fp_fmax_zero_float: 89; CHECK: # %bb.0: 90; CHECK-NEXT: fmax.s %s0, %s0, (0)1 91; CHECK-NEXT: b.l.t (, %s10) 92 %2 = tail call fast float @llvm.maxnum.f32(float %0, float 0.000000e+00) 93 ret float %2 94} 95 96; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn 97define double @func_fp_fmax_zero_double(double noundef %0) { 98; CHECK-LABEL: func_fp_fmax_zero_double: 99; CHECK: # %bb.0: 100; CHECK-NEXT: fmax.d %s0, %s0, (0)1 101; CHECK-NEXT: b.l.t (, %s10) 102 %2 = tail call fast double @llvm.maxnum.f64(double %0, double 0.000000e+00) 103 ret double %2 104} 105 106; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn 107define fp128 @func_fp_fmax_zero_quad(fp128 noundef %0) { 108; CHECK-LABEL: func_fp_fmax_zero_quad: 109; CHECK: # %bb.0: 110; CHECK-NEXT: lea %s2, .LCPI{{[0-9]+}}_0@lo 111; CHECK-NEXT: and %s2, %s2, (32)0 112; CHECK-NEXT: lea.sl %s4, .LCPI{{[0-9]+}}_0@hi(, %s2) 113; CHECK-NEXT: ld %s2, 8(, %s4) 114; CHECK-NEXT: ld %s3, (, %s4) 115; CHECK-NEXT: fcmp.q %s4, %s0, %s2 116; CHECK-NEXT: cmov.d.gt %s2, %s0, %s4 117; CHECK-NEXT: cmov.d.gt %s3, %s1, %s4 118; CHECK-NEXT: or %s0, 0, %s2 119; CHECK-NEXT: or %s1, 0, %s3 120; CHECK-NEXT: b.l.t (, %s10) 121 %2 = tail call fast fp128 @llvm.maxnum.f128(fp128 %0, fp128 0xL00000000000000000000000000000000) 122 ret fp128 %2 123} 124 125; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn 126define float @func_fp_fmax_const_float(float noundef %0) { 127; CHECK-LABEL: func_fp_fmax_const_float: 128; CHECK: # %bb.0: 129; CHECK-NEXT: fmax.s %s0, %s0, (2)1 130; CHECK-NEXT: b.l.t (, %s10) 131 %2 = tail call fast float @llvm.maxnum.f32(float %0, float -2.000000e+00) 132 ret float %2 133} 134 135; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn 136define double @func_fp_fmax_const_double(double noundef %0) { 137; CHECK-LABEL: func_fp_fmax_const_double: 138; CHECK: # %bb.0: 139; CHECK-NEXT: fmax.d %s0, %s0, (2)1 140; CHECK-NEXT: b.l.t (, %s10) 141 %2 = tail call fast double @llvm.maxnum.f64(double %0, double -2.000000e+00) 142 ret double %2 143} 144 145; Function Attrs: mustprogress nofree nosync nounwind readnone willreturn 146define fp128 @func_fp_fmax_const_quad(fp128 noundef %0) { 147; CHECK-LABEL: func_fp_fmax_const_quad: 148; CHECK: # %bb.0: 149; CHECK-NEXT: lea %s2, .LCPI{{[0-9]+}}_0@lo 150; CHECK-NEXT: and %s2, %s2, (32)0 151; CHECK-NEXT: lea.sl %s4, .LCPI{{[0-9]+}}_0@hi(, %s2) 152; CHECK-NEXT: ld %s2, 8(, %s4) 153; CHECK-NEXT: ld %s3, (, %s4) 154; CHECK-NEXT: fcmp.q %s4, %s0, %s2 155; CHECK-NEXT: cmov.d.gt %s2, %s0, %s4 156; CHECK-NEXT: cmov.d.gt %s3, %s1, %s4 157; CHECK-NEXT: or %s0, 0, %s2 158; CHECK-NEXT: or %s1, 0, %s3 159; CHECK-NEXT: b.l.t (, %s10) 160 %2 = tail call fast fp128 @llvm.maxnum.f128(fp128 %0, fp128 0xL0000000000000000C000000000000000) 161 ret fp128 %2 162} 163