diff --git a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-rootn.ll b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-rootn.ll new file mode 100644 index 0000000000000..421b2d88dcfe9 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-rootn.ll @@ -0,0 +1,1497 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 4 +; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -passes=amdgpu-simplifylib,instcombine -amdgpu-prelink %s | FileCheck %s + +target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8" + +declare float @_Z5rootnfi(float, i32) +declare <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float>, <2 x i32>) +declare <3 x float> @_Z5rootnDv3_fDv3_i(<3 x float>, <3 x i32>) +declare <4 x float> @_Z5rootnDv4_fDv4_i(<4 x float>, <4 x i32>) +declare <8 x float> @_Z5rootnDv8_fDv8_i(<8 x float>, <8 x i32>) +declare <16 x float> @_Z5rootnDv16_fDv16_i(<16 x float>, <16 x i32>) +declare double @_Z5rootndi(double, i32) +declare <2 x double> @_Z5rootnDv2_dDv2_i(<2 x double>, <2 x i32>) +declare <3 x double> @_Z5rootnDv3_dDv3_i(<3 x double>, <3 x i32>) +declare <4 x double> @_Z5rootnDv4_dDv4_i(<4 x double>, <4 x i32>) +declare <8 x double> @_Z5rootnDv8_dDv8_i(<8 x double>, <8 x i32>) +declare <16 x double> @_Z5rootnDv16_dDv16_i(<16 x double>, <16 x i32>) +declare half @_Z5rootnDhi(half, i32) +declare <2 x half> @_Z5rootnDv2_DhDv2_i(<2 x half>, <2 x i32>) +declare <3 x half> @_Z5rootnDv3_DhDv3_i(<3 x half>, <3 x i32>) +declare <4 x half> @_Z5rootnDv4_DhDv4_i(<4 x half>, <4 x i32>) +declare <8 x half> @_Z5rootnDv8_DhDv8_i(<8 x half>, <8 x i32>) +declare <16 x half> @_Z5rootnDv16_DhDv16_i(<16 x half>, <16 x i32>) + +define float @test_rootn_f32(float %x, i32 %y) { +; CHECK-LABEL: define float @test_rootn_f32( +; CHECK-SAME: float [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 [[Y]]) +; CHECK-NEXT: ret float [[CALL]] +; +entry: + %call = tail call float @_Z5rootnfi(float %x, i32 %y) + ret float %call +} + +define float @test_rootn_f32_flags(float %x, i32 %y) { +; CHECK-LABEL: define float @test_rootn_f32_flags( +; CHECK-SAME: float [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call nnan nsz float @_Z5rootnfi(float [[X]], i32 [[Y]]) +; CHECK-NEXT: ret float [[CALL]] +; +entry: + %call = tail call nnan nsz float @_Z5rootnfi(float %x, i32 %y) + ret float %call +} + +define <2 x float> @test_rootn_v2f32(<2 x float> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x float> @test_rootn_v2f32( +; CHECK-SAME: <2 x float> [[X:%.*]], <2 x i32> [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: ret <2 x float> [[CALL]] +; +entry: + %call = tail call <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> %x, <2 x i32> %y) + ret <2 x float> %call +} + +define <3 x float> @test_rootn_v3f32(<3 x float> %x, <3 x i32> %y) { +; CHECK-LABEL: define <3 x float> @test_rootn_v3f32( +; CHECK-SAME: <3 x float> [[X:%.*]], <3 x i32> [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <3 x float> @_Z5rootnDv3_fDv3_i(<3 x float> [[X]], <3 x i32> [[Y]]) +; CHECK-NEXT: ret <3 x float> [[CALL]] +; +entry: + %call = tail call <3 x float> @_Z5rootnDv3_fDv3_i(<3 x float> %x, <3 x i32> %y) + ret <3 x float> %call +} + +define <4 x float> @test_rootn_v4f32(<4 x float> %x, <4 x i32> %y) { +; CHECK-LABEL: define <4 x float> @test_rootn_v4f32( +; CHECK-SAME: <4 x float> [[X:%.*]], <4 x i32> [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <4 x float> @_Z5rootnDv4_fDv4_i(<4 x float> [[X]], <4 x i32> [[Y]]) +; CHECK-NEXT: ret <4 x float> [[CALL]] +; +entry: + %call = tail call <4 x float> @_Z5rootnDv4_fDv4_i(<4 x float> %x, <4 x i32> %y) + ret <4 x float> %call +} + +define <8 x float> @test_rootn_v8f32(<8 x float> %x, <8 x i32> %y) { +; CHECK-LABEL: define <8 x float> @test_rootn_v8f32( +; CHECK-SAME: <8 x float> [[X:%.*]], <8 x i32> [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <8 x float> @_Z5rootnDv8_fDv8_i(<8 x float> [[X]], <8 x i32> [[Y]]) +; CHECK-NEXT: ret <8 x float> [[CALL]] +; +entry: + %call = tail call <8 x float> @_Z5rootnDv8_fDv8_i(<8 x float> %x, <8 x i32> %y) + ret <8 x float> %call +} + +define <16 x float> @test_rootn_v16f32(<16 x float> %x, <16 x i32> %y) { +; CHECK-LABEL: define <16 x float> @test_rootn_v16f32( +; CHECK-SAME: <16 x float> [[X:%.*]], <16 x i32> [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <16 x float> @_Z5rootnDv16_fDv16_i(<16 x float> [[X]], <16 x i32> [[Y]]) +; CHECK-NEXT: ret <16 x float> [[CALL]] +; +entry: + %call = tail call <16 x float> @_Z5rootnDv16_fDv16_i(<16 x float> %x, <16 x i32> %y) + ret <16 x float> %call +} + +define double @test_rootn_f64(double %x, i32 %y) { +; CHECK-LABEL: define double @test_rootn_f64( +; CHECK-SAME: double [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call double @_Z5rootndi(double [[X]], i32 [[Y]]) +; CHECK-NEXT: ret double [[CALL]] +; +entry: + %call = tail call double @_Z5rootndi(double %x, i32 %y) + ret double %call +} + +define <2 x double> @test_rootn_v2f64(<2 x double> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x double> @test_rootn_v2f64( +; CHECK-SAME: <2 x double> [[X:%.*]], <2 x i32> [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <2 x double> @_Z5rootnDv2_dDv2_i(<2 x double> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: ret <2 x double> [[CALL]] +; +entry: + %call = tail call <2 x double> @_Z5rootnDv2_dDv2_i(<2 x double> %x, <2 x i32> %y) + ret <2 x double> %call +} + +define <3 x double> @test_rootn_v3f64(<3 x double> %x, <3 x i32> %y) { +; CHECK-LABEL: define <3 x double> @test_rootn_v3f64( +; CHECK-SAME: <3 x double> [[X:%.*]], <3 x i32> [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <3 x double> @_Z5rootnDv3_dDv3_i(<3 x double> [[X]], <3 x i32> [[Y]]) +; CHECK-NEXT: ret <3 x double> [[CALL]] +; +entry: + %call = tail call <3 x double> @_Z5rootnDv3_dDv3_i(<3 x double> %x, <3 x i32> %y) + ret <3 x double> %call +} + +define <4 x double> @test_rootn_v4f64(<4 x double> %x, <4 x i32> %y) { +; CHECK-LABEL: define <4 x double> @test_rootn_v4f64( +; CHECK-SAME: <4 x double> [[X:%.*]], <4 x i32> [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <4 x double> @_Z5rootnDv4_dDv4_i(<4 x double> [[X]], <4 x i32> [[Y]]) +; CHECK-NEXT: ret <4 x double> [[CALL]] +; +entry: + %call = tail call <4 x double> @_Z5rootnDv4_dDv4_i(<4 x double> %x, <4 x i32> %y) + ret <4 x double> %call +} + +define <8 x double> @test_rootn_v8f64(<8 x double> %x, <8 x i32> %y) { +; CHECK-LABEL: define <8 x double> @test_rootn_v8f64( +; CHECK-SAME: <8 x double> [[X:%.*]], <8 x i32> [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <8 x double> @_Z5rootnDv8_dDv8_i(<8 x double> [[X]], <8 x i32> [[Y]]) +; CHECK-NEXT: ret <8 x double> [[CALL]] +; +entry: + %call = tail call <8 x double> @_Z5rootnDv8_dDv8_i(<8 x double> %x, <8 x i32> %y) + ret <8 x double> %call +} + +define <16 x double> @test_rootn_v16f64(<16 x double> %x, <16 x i32> %y) { +; CHECK-LABEL: define <16 x double> @test_rootn_v16f64( +; CHECK-SAME: <16 x double> [[X:%.*]], <16 x i32> [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <16 x double> @_Z5rootnDv16_dDv16_i(<16 x double> [[X]], <16 x i32> [[Y]]) +; CHECK-NEXT: ret <16 x double> [[CALL]] +; +entry: + %call = tail call <16 x double> @_Z5rootnDv16_dDv16_i(<16 x double> %x, <16 x i32> %y) + ret <16 x double> %call +} + +define half @test_rootn_f16(half %x, i32 %y) { +; CHECK-LABEL: define half @test_rootn_f16( +; CHECK-SAME: half [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call half @_Z5rootnDhi(half [[X]], i32 [[Y]]) +; CHECK-NEXT: ret half [[CALL]] +; +entry: + %call = tail call half @_Z5rootnDhi(half %x, i32 %y) + ret half %call +} + +define <2 x half> @test_rootn_v2f16(<2 x half> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x half> @test_rootn_v2f16( +; CHECK-SAME: <2 x half> [[X:%.*]], <2 x i32> [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <2 x half> @_Z5rootnDv2_DhDv2_i(<2 x half> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: ret <2 x half> [[CALL]] +; +entry: + %call = tail call <2 x half> @_Z5rootnDv2_DhDv2_i(<2 x half> %x, <2 x i32> %y) + ret <2 x half> %call +} + +define <3 x half> @test_rootn_v3f16(<3 x half> %x, <3 x i32> %y) { +; CHECK-LABEL: define <3 x half> @test_rootn_v3f16( +; CHECK-SAME: <3 x half> [[X:%.*]], <3 x i32> [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <3 x half> @_Z5rootnDv3_DhDv3_i(<3 x half> [[X]], <3 x i32> [[Y]]) +; CHECK-NEXT: ret <3 x half> [[CALL]] +; +entry: + %call = tail call <3 x half> @_Z5rootnDv3_DhDv3_i(<3 x half> %x, <3 x i32> %y) + ret <3 x half> %call +} + +define <4 x half> @test_rootn_v4f16(<4 x half> %x, <4 x i32> %y) { +; CHECK-LABEL: define <4 x half> @test_rootn_v4f16( +; CHECK-SAME: <4 x half> [[X:%.*]], <4 x i32> [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <4 x half> @_Z5rootnDv4_DhDv4_i(<4 x half> [[X]], <4 x i32> [[Y]]) +; CHECK-NEXT: ret <4 x half> [[CALL]] +; +entry: + %call = tail call <4 x half> @_Z5rootnDv4_DhDv4_i(<4 x half> %x, <4 x i32> %y) + ret <4 x half> %call +} + +define <8 x half> @test_rootn_v8f16(<8 x half> %x, <8 x i32> %y) { +; CHECK-LABEL: define <8 x half> @test_rootn_v8f16( +; CHECK-SAME: <8 x half> [[X:%.*]], <8 x i32> [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <8 x half> @_Z5rootnDv8_DhDv8_i(<8 x half> [[X]], <8 x i32> [[Y]]) +; CHECK-NEXT: ret <8 x half> [[CALL]] +; +entry: + %call = tail call <8 x half> @_Z5rootnDv8_DhDv8_i(<8 x half> %x, <8 x i32> %y) + ret <8 x half> %call +} + +define <16 x half> @test_rootn_v16f16(<16 x half> %x, <16 x i32> %y) { +; CHECK-LABEL: define <16 x half> @test_rootn_v16f16( +; CHECK-SAME: <16 x half> [[X:%.*]], <16 x i32> [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <16 x half> @_Z5rootnDv16_DhDv16_i(<16 x half> [[X]], <16 x i32> [[Y]]) +; CHECK-NEXT: ret <16 x half> [[CALL]] +; +entry: + %call = tail call <16 x half> @_Z5rootnDv16_DhDv16_i(<16 x half> %x, <16 x i32> %y) + ret <16 x half> %call +} + +define half @test_rootn_f16_0(half %x) { +; CHECK-LABEL: define half @test_rootn_f16_0( +; CHECK-SAME: half [[X:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = tail call half @_Z5rootnDhi(half [[X]], i32 0) +; CHECK-NEXT: ret half [[CALL]] +; + %call = tail call half @_Z5rootnDhi(half %x, i32 0) + ret half %call +} + +define half @test_rootn_f16_1(half %x) { +; CHECK-LABEL: define half @test_rootn_f16_1( +; CHECK-SAME: half [[X:%.*]]) { +; CHECK-NEXT: ret half [[X]] +; + %call = tail call half @_Z5rootnDhi(half %x, i32 1) + ret half %call +} + +define half @test_rootn_f16_2(half %x) { +; CHECK-LABEL: define half @test_rootn_f16_2( +; CHECK-SAME: half [[X:%.*]]) { +; CHECK-NEXT: [[__ROOTN2SQRT:%.*]] = call half @_Z4sqrtDh(half [[X]]) +; CHECK-NEXT: ret half [[__ROOTN2SQRT]] +; + %call = tail call half @_Z5rootnDhi(half %x, i32 2) + ret half %call +} + +define half @test_rootn_f16_3(half %x) { +; CHECK-LABEL: define half @test_rootn_f16_3( +; CHECK-SAME: half [[X:%.*]]) { +; CHECK-NEXT: [[__ROOTN2CBRT:%.*]] = call half @_Z4cbrtDh(half [[X]]) +; CHECK-NEXT: ret half [[__ROOTN2CBRT]] +; + %call = tail call half @_Z5rootnDhi(half %x, i32 3) + ret half %call +} + +define half @test_rootn_f16_neg1(half %x) { +; CHECK-LABEL: define half @test_rootn_f16_neg1( +; CHECK-SAME: half [[X:%.*]]) { +; CHECK-NEXT: [[__ROOTN2DIV:%.*]] = fdiv half 0xH3C00, [[X]] +; CHECK-NEXT: ret half [[__ROOTN2DIV]] +; + %call = tail call half @_Z5rootnDhi(half %x, i32 -1) + ret half %call +} + +define half @test_rootn_f16_neg2(half %x) { +; CHECK-LABEL: define half @test_rootn_f16_neg2( +; CHECK-SAME: half [[X:%.*]]) { +; CHECK-NEXT: [[__ROOTN2RSQRT:%.*]] = call half @_Z5rsqrtDh(half [[X]]) +; CHECK-NEXT: ret half [[__ROOTN2RSQRT]] +; + %call = tail call half @_Z5rootnDhi(half %x, i32 -2) + ret half %call +} + +define half @test_rootn_f16_neg3(half %x) { +; CHECK-LABEL: define half @test_rootn_f16_neg3( +; CHECK-SAME: half [[X:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = tail call half @_Z5rootnDhi(half [[X]], i32 -3) +; CHECK-NEXT: ret half [[CALL]] +; + %call = tail call half @_Z5rootnDhi(half %x, i32 -3) + ret half %call +} + +define half @test_rootn_f16_neg4(half %x) { +; CHECK-LABEL: define half @test_rootn_f16_neg4( +; CHECK-SAME: half [[X:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = tail call half @_Z5rootnDhi(half [[X]], i32 -4) +; CHECK-NEXT: ret half [[CALL]] +; + %call = tail call half @_Z5rootnDhi(half %x, i32 -4) + ret half %call +} + +define <2 x half> @test_rootn_v2f16_0(<2 x half> %x) { +; CHECK-LABEL: define <2 x half> @test_rootn_v2f16_0( +; CHECK-SAME: <2 x half> [[X:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = tail call <2 x half> @_Z5rootnDv2_DhDv2_i(<2 x half> [[X]], <2 x i32> zeroinitializer) +; CHECK-NEXT: ret <2 x half> [[CALL]] +; + %call = tail call <2 x half> @_Z5rootnDv2_DhDv2_i(<2 x half> %x, <2 x i32> zeroinitializer) + ret <2 x half> %call +} + +define <2 x half> @test_rootn_v2f16_1(<2 x half> %x) { +; CHECK-LABEL: define <2 x half> @test_rootn_v2f16_1( +; CHECK-SAME: <2 x half> [[X:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = tail call <2 x half> @_Z5rootnDv2_DhDv2_i(<2 x half> [[X]], <2 x i32> ) +; CHECK-NEXT: ret <2 x half> [[CALL]] +; + %call = tail call <2 x half> @_Z5rootnDv2_DhDv2_i(<2 x half> %x, <2 x i32> ) + ret <2 x half> %call +} + +define <2 x half> @test_rootn_v2f16_2(<2 x half> %x) { +; CHECK-LABEL: define <2 x half> @test_rootn_v2f16_2( +; CHECK-SAME: <2 x half> [[X:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = tail call <2 x half> @_Z5rootnDv2_DhDv2_i(<2 x half> [[X]], <2 x i32> ) +; CHECK-NEXT: ret <2 x half> [[CALL]] +; + %call = tail call <2 x half> @_Z5rootnDv2_DhDv2_i(<2 x half> %x, <2 x i32> ) + ret <2 x half> %call +} + +define <2 x half> @test_rootn_v2f16_neg1(<2 x half> %x) { +; CHECK-LABEL: define <2 x half> @test_rootn_v2f16_neg1( +; CHECK-SAME: <2 x half> [[X:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = tail call <2 x half> @_Z5rootnDv2_DhDv2_i(<2 x half> [[X]], <2 x i32> ) +; CHECK-NEXT: ret <2 x half> [[CALL]] +; + %call = tail call <2 x half> @_Z5rootnDv2_DhDv2_i(<2 x half> %x, <2 x i32> ) + ret <2 x half> %call +} + +define <2 x half> @test_rootn_v2f16_neg2(<2 x half> %x) { +; CHECK-LABEL: define <2 x half> @test_rootn_v2f16_neg2( +; CHECK-SAME: <2 x half> [[X:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = tail call <2 x half> @_Z5rootnDv2_DhDv2_i(<2 x half> [[X]], <2 x i32> ) +; CHECK-NEXT: ret <2 x half> [[CALL]] +; + %call = tail call <2 x half> @_Z5rootnDv2_DhDv2_i(<2 x half> %x, <2 x i32> ) + ret <2 x half> %call +} + +define <2 x half> @test_rootn_v2f16_neg3(<2 x half> %x) { +; CHECK-LABEL: define <2 x half> @test_rootn_v2f16_neg3( +; CHECK-SAME: <2 x half> [[X:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = tail call <2 x half> @_Z5rootnDv2_DhDv2_i(<2 x half> [[X]], <2 x i32> ) +; CHECK-NEXT: ret <2 x half> [[CALL]] +; + %call = tail call <2 x half> @_Z5rootnDv2_DhDv2_i(<2 x half> %x, <2 x i32> ) + ret <2 x half> %call +} + +define float @test_rootn_f32__y_0(float %x) { +; CHECK-LABEL: define float @test_rootn_f32__y_0( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 0) +; CHECK-NEXT: ret float [[CALL]] +; +entry: + %call = tail call float @_Z5rootnfi(float %x, i32 0) + ret float %call +} + +define float @test_rootn_f32__y_poison(float %x) { +; CHECK-LABEL: define float @test_rootn_f32__y_poison( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 poison) +; CHECK-NEXT: ret float [[CALL]] +; +entry: + %call = tail call float @_Z5rootnfi(float %x, i32 poison) + ret float %call +} + +define <2 x float> @test_rootn_v2f32__y_poison(<2 x float> %x) { +; CHECK-LABEL: define <2 x float> @test_rootn_v2f32__y_poison( +; CHECK-SAME: <2 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> poison) +; CHECK-NEXT: ret <2 x float> [[CALL]] +; +entry: + %call = tail call <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> %x, <2 x i32> poison) + ret <2 x float> %call +} + +define <2 x float> @test_rootn_v2f32__y_0(<2 x float> %x) { +; CHECK-LABEL: define <2 x float> @test_rootn_v2f32__y_0( +; CHECK-SAME: <2 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> zeroinitializer) +; CHECK-NEXT: ret <2 x float> [[CALL]] +; +entry: + %call = tail call <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> %x, <2 x i32> zeroinitializer) + ret <2 x float> %call +} + +define <2 x float> @test_rootn_v2f32__y_0_undef(<2 x float> %x) { +; CHECK-LABEL: define <2 x float> @test_rootn_v2f32__y_0_undef( +; CHECK-SAME: <2 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> ) +; CHECK-NEXT: ret <2 x float> [[CALL]] +; +entry: + %call = tail call <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> %x, <2 x i32> ) + ret <2 x float> %call +} + +define <3 x float> @test_rootn_v3f32__y_0(<3 x float> %x) { +; CHECK-LABEL: define <3 x float> @test_rootn_v3f32__y_0( +; CHECK-SAME: <3 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <3 x float> @_Z5rootnDv3_fDv3_i(<3 x float> [[X]], <3 x i32> zeroinitializer) +; CHECK-NEXT: ret <3 x float> [[CALL]] +; +entry: + %call = tail call <3 x float> @_Z5rootnDv3_fDv3_i(<3 x float> %x, <3 x i32> zeroinitializer) + ret <3 x float> %call +} + +define <4 x float> @test_rootn_v4f32__y_0(<4 x float> %x) { +; CHECK-LABEL: define <4 x float> @test_rootn_v4f32__y_0( +; CHECK-SAME: <4 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <4 x float> @_Z5rootnDv4_fDv4_i(<4 x float> [[X]], <4 x i32> zeroinitializer) +; CHECK-NEXT: ret <4 x float> [[CALL]] +; +entry: + %call = tail call <4 x float> @_Z5rootnDv4_fDv4_i(<4 x float> %x, <4 x i32> zeroinitializer) + ret <4 x float> %call +} + +define <8 x float> @test_rootn_v8f32__y_0(<8 x float> %x) { +; CHECK-LABEL: define <8 x float> @test_rootn_v8f32__y_0( +; CHECK-SAME: <8 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <8 x float> @_Z5rootnDv8_fDv8_i(<8 x float> [[X]], <8 x i32> zeroinitializer) +; CHECK-NEXT: ret <8 x float> [[CALL]] +; +entry: + %call = tail call <8 x float> @_Z5rootnDv8_fDv8_i(<8 x float> %x, <8 x i32> zeroinitializer) + ret <8 x float> %call +} + +define <16 x float> @test_rootn_v16f32__y_0(<16 x float> %x) { +; CHECK-LABEL: define <16 x float> @test_rootn_v16f32__y_0( +; CHECK-SAME: <16 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <16 x float> @_Z5rootnDv16_fDv16_i(<16 x float> [[X]], <16 x i32> zeroinitializer) +; CHECK-NEXT: ret <16 x float> [[CALL]] +; +entry: + %call = tail call <16 x float> @_Z5rootnDv16_fDv16_i(<16 x float> %x, <16 x i32> zeroinitializer) + ret <16 x float> %call +} + +define float @test_rootn_f32__y_1(float %x) { +; CHECK-LABEL: define float @test_rootn_f32__y_1( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: ret float [[X]] +; +entry: + %call = tail call float @_Z5rootnfi(float %x, i32 1) + ret float %call +} + +define float @test_rootn_f32__y_1__strictfp(float %x) #1 { +; CHECK-LABEL: define float @test_rootn_f32__y_1__strictfp( +; CHECK-SAME: float [[X:%.*]]) #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: ret float [[X]] +; +entry: + %call = tail call float @_Z5rootnfi(float %x, i32 1) #1 + ret float %call +} + +define <2 x float> @test_rootn_v2f32__y_1(<2 x float> %x) { +; CHECK-LABEL: define <2 x float> @test_rootn_v2f32__y_1( +; CHECK-SAME: <2 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> ) +; CHECK-NEXT: ret <2 x float> [[CALL]] +; +entry: + %call = tail call <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> %x, <2 x i32> ) + ret <2 x float> %call +} + +define <2 x float> @test_rootn_v2f32__y_1__strictfp(<2 x float> %x) #1 { +; CHECK-LABEL: define <2 x float> @test_rootn_v2f32__y_1__strictfp( +; CHECK-SAME: <2 x float> [[X:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> ) #[[ATTR0]] +; CHECK-NEXT: ret <2 x float> [[CALL]] +; +entry: + %call = tail call <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> %x, <2 x i32> ) #1 + ret <2 x float> %call +} + +define <2 x float> @test_rootn_v2f32__y_1_undef(<2 x float> %x) { +; CHECK-LABEL: define <2 x float> @test_rootn_v2f32__y_1_undef( +; CHECK-SAME: <2 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> ) +; CHECK-NEXT: ret <2 x float> [[CALL]] +; +entry: + %call = tail call <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> %x, <2 x i32> ) + ret <2 x float> %call +} + +define <3 x float> @test_rootn_v3f32__y_1(<3 x float> %x) { +; CHECK-LABEL: define <3 x float> @test_rootn_v3f32__y_1( +; CHECK-SAME: <3 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <3 x float> @_Z5rootnDv3_fDv3_i(<3 x float> [[X]], <3 x i32> ) +; CHECK-NEXT: ret <3 x float> [[CALL]] +; +entry: + %call = tail call <3 x float> @_Z5rootnDv3_fDv3_i(<3 x float> %x, <3 x i32> ) + ret <3 x float> %call +} + +define <3 x float> @test_rootn_v3f32__y_1_undef(<3 x float> %x) { +; CHECK-LABEL: define <3 x float> @test_rootn_v3f32__y_1_undef( +; CHECK-SAME: <3 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <3 x float> @_Z5rootnDv3_fDv3_i(<3 x float> [[X]], <3 x i32> ) +; CHECK-NEXT: ret <3 x float> [[CALL]] +; +entry: + %call = tail call <3 x float> @_Z5rootnDv3_fDv3_i(<3 x float> %x, <3 x i32> ) + ret <3 x float> %call +} + +define <4 x float> @test_rootn_v4f32__y_1(<4 x float> %x) { +; CHECK-LABEL: define <4 x float> @test_rootn_v4f32__y_1( +; CHECK-SAME: <4 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <4 x float> @_Z5rootnDv4_fDv4_i(<4 x float> [[X]], <4 x i32> ) +; CHECK-NEXT: ret <4 x float> [[CALL]] +; +entry: + %call = tail call <4 x float> @_Z5rootnDv4_fDv4_i(<4 x float> %x, <4 x i32> ) + ret <4 x float> %call +} + +define <8 x float> @test_rootn_v8f32__y_1(<8 x float> %x) { +; CHECK-LABEL: define <8 x float> @test_rootn_v8f32__y_1( +; CHECK-SAME: <8 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <8 x float> @_Z5rootnDv8_fDv8_i(<8 x float> [[X]], <8 x i32> ) +; CHECK-NEXT: ret <8 x float> [[CALL]] +; +entry: + %call = tail call <8 x float> @_Z5rootnDv8_fDv8_i(<8 x float> %x, <8 x i32> ) + ret <8 x float> %call +} + +define <16 x float> @test_rootn_v16f32__y_1(<16 x float> %x) { +; CHECK-LABEL: define <16 x float> @test_rootn_v16f32__y_1( +; CHECK-SAME: <16 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <16 x float> @_Z5rootnDv16_fDv16_i(<16 x float> [[X]], <16 x i32> ) +; CHECK-NEXT: ret <16 x float> [[CALL]] +; +entry: + %call = tail call <16 x float> @_Z5rootnDv16_fDv16_i(<16 x float> %x, <16 x i32> ) + ret <16 x float> %call +} + +define float @test_rootn_f32__y_2(float %x) { +; CHECK-LABEL: define float @test_rootn_f32__y_2( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[__ROOTN2SQRT:%.*]] = call float @_Z4sqrtf(float [[X]]) +; CHECK-NEXT: ret float [[__ROOTN2SQRT]] +; +entry: + %call = tail call float @_Z5rootnfi(float %x, i32 2) + ret float %call +} + +define float @test_rootn_f32__y_2_flags(float %x) { +; CHECK-LABEL: define float @test_rootn_f32__y_2_flags( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[__ROOTN2SQRT:%.*]] = call nnan nsz float @_Z4sqrtf(float [[X]]) +; CHECK-NEXT: ret float [[__ROOTN2SQRT]] +; +entry: + %call = tail call nnan nsz float @_Z5rootnfi(float %x, i32 2) + ret float %call +} + +; Should retain looser existing !fpmath requirements. +define float @test_rootn_f32__y_2_fpmath_3(float %x) { +; CHECK-LABEL: define float @test_rootn_f32__y_2_fpmath_3( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[__ROOTN2SQRT:%.*]] = call nnan nsz float @_Z4sqrtf(float [[X]]) +; CHECK-NEXT: ret float [[__ROOTN2SQRT]] +; +entry: + %call = tail call nnan nsz float @_Z5rootnfi(float %x, i32 2), !fpmath !0 + ret float %call +} + +define <2 x float> @test_rootn_v2f32__y_2_flags(<2 x float> %x) { +; CHECK-LABEL: define <2 x float> @test_rootn_v2f32__y_2_flags( +; CHECK-SAME: <2 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call nnan nsz <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> ) +; CHECK-NEXT: ret <2 x float> [[CALL]] +; +entry: + %call = tail call nnan nsz <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> %x, <2 x i32> ) + ret <2 x float> %call +} + +define <3 x float> @test_rootn_v3f32__y_2(<3 x float> %x) { +; CHECK-LABEL: define <3 x float> @test_rootn_v3f32__y_2( +; CHECK-SAME: <3 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <3 x float> @_Z5rootnDv3_fDv3_i(<3 x float> [[X]], <3 x i32> ) +; CHECK-NEXT: ret <3 x float> [[CALL]] +; +entry: + %call = tail call <3 x float> @_Z5rootnDv3_fDv3_i(<3 x float> %x, <3 x i32> ) + ret <3 x float> %call +} + +define <3 x float> @test_rootn_v3f32__y_2_undef(<3 x float> %x) { +; CHECK-LABEL: define <3 x float> @test_rootn_v3f32__y_2_undef( +; CHECK-SAME: <3 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <3 x float> @_Z5rootnDv3_fDv3_i(<3 x float> [[X]], <3 x i32> ) +; CHECK-NEXT: ret <3 x float> [[CALL]] +; +entry: + %call = tail call <3 x float> @_Z5rootnDv3_fDv3_i(<3 x float> %x, <3 x i32> ) + ret <3 x float> %call +} + +define <4 x float> @test_rootn_v4f32__y_2(<4 x float> %x) { +; CHECK-LABEL: define <4 x float> @test_rootn_v4f32__y_2( +; CHECK-SAME: <4 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <4 x float> @_Z5rootnDv4_fDv4_i(<4 x float> [[X]], <4 x i32> ) +; CHECK-NEXT: ret <4 x float> [[CALL]] +; +entry: + %call = tail call <4 x float> @_Z5rootnDv4_fDv4_i(<4 x float> %x, <4 x i32> ) + ret <4 x float> %call +} + +define <8 x float> @test_rootn_v8f32__y_2(<8 x float> %x) { +; CHECK-LABEL: define <8 x float> @test_rootn_v8f32__y_2( +; CHECK-SAME: <8 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <8 x float> @_Z5rootnDv8_fDv8_i(<8 x float> [[X]], <8 x i32> ) +; CHECK-NEXT: ret <8 x float> [[CALL]] +; +entry: + %call = tail call <8 x float> @_Z5rootnDv8_fDv8_i(<8 x float> %x, <8 x i32> ) + ret <8 x float> %call +} + +define <16 x float> @test_rootn_v16f32__y_2(<16 x float> %x) { +; CHECK-LABEL: define <16 x float> @test_rootn_v16f32__y_2( +; CHECK-SAME: <16 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <16 x float> @_Z5rootnDv16_fDv16_i(<16 x float> [[X]], <16 x i32> ) +; CHECK-NEXT: ret <16 x float> [[CALL]] +; +entry: + %call = tail call <16 x float> @_Z5rootnDv16_fDv16_i(<16 x float> %x, <16 x i32> ) + ret <16 x float> %call +} + +define float @test_rootn_f32__y_3(float %x) { +; CHECK-LABEL: define float @test_rootn_f32__y_3( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[__ROOTN2CBRT:%.*]] = call float @_Z4cbrtf(float [[X]]) +; CHECK-NEXT: ret float [[__ROOTN2CBRT]] +; +entry: + %call = tail call float @_Z5rootnfi(float %x, i32 3) + ret float %call +} + +define <2 x float> @test_rootn_v2f32__y_3(<2 x float> %x) { +; CHECK-LABEL: define <2 x float> @test_rootn_v2f32__y_3( +; CHECK-SAME: <2 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> ) +; CHECK-NEXT: ret <2 x float> [[CALL]] +; +entry: + %call = tail call <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> %x, <2 x i32> ) + ret <2 x float> %call +} + +define <2 x float> @test_rootn_v2f32__y_nonsplat_2_3(<2 x float> %x) { +; CHECK-LABEL: define <2 x float> @test_rootn_v2f32__y_nonsplat_2_3( +; CHECK-SAME: <2 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> ) +; CHECK-NEXT: ret <2 x float> [[CALL]] +; +entry: + %call = tail call <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> %x, <2 x i32> ) + ret <2 x float> %call +} + +define <2 x float> @test_rootn_v2f32__y_nonsplat_2_poison(<2 x float> %x) { +; CHECK-LABEL: define <2 x float> @test_rootn_v2f32__y_nonsplat_2_poison( +; CHECK-SAME: <2 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> ) +; CHECK-NEXT: ret <2 x float> [[CALL]] +; +entry: + %call = tail call <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> %x, <2 x i32> ) + ret <2 x float> %call +} + +define <2 x float> @test_rootn_v2f32__y_nonsplat_2_5(<2 x float> %x) { +; CHECK-LABEL: define <2 x float> @test_rootn_v2f32__y_nonsplat_2_5( +; CHECK-SAME: <2 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> ) +; CHECK-NEXT: ret <2 x float> [[CALL]] +; +entry: + %call = tail call <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> %x, <2 x i32> ) + ret <2 x float> %call +} + +define float @test_rootn_f32__y_neg1(float %x) { +; CHECK-LABEL: define float @test_rootn_f32__y_neg1( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[__ROOTN2DIV:%.*]] = fdiv float 1.000000e+00, [[X]] +; CHECK-NEXT: ret float [[__ROOTN2DIV]] +; +entry: + %call = tail call float @_Z5rootnfi(float %x, i32 -1) + ret float %call +} + +define <2 x float> @test_rootn_v2f32__y_neg1(<2 x float> %x) { +; CHECK-LABEL: define <2 x float> @test_rootn_v2f32__y_neg1( +; CHECK-SAME: <2 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> ) +; CHECK-NEXT: ret <2 x float> [[CALL]] +; +entry: + %call = tail call <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> %x, <2 x i32> ) + ret <2 x float> %call +} + +define <3 x float> @test_rootn_v3f32__y_neg1(<3 x float> %x) { +; CHECK-LABEL: define <3 x float> @test_rootn_v3f32__y_neg1( +; CHECK-SAME: <3 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <3 x float> @_Z5rootnDv3_fDv3_i(<3 x float> [[X]], <3 x i32> ) +; CHECK-NEXT: ret <3 x float> [[CALL]] +; +entry: + %call = tail call <3 x float> @_Z5rootnDv3_fDv3_i(<3 x float> %x, <3 x i32> ) + ret <3 x float> %call +} + +define <3 x float> @test_rootn_v3f32__y_neg1_undef(<3 x float> %x) { +; CHECK-LABEL: define <3 x float> @test_rootn_v3f32__y_neg1_undef( +; CHECK-SAME: <3 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <3 x float> @_Z5rootnDv3_fDv3_i(<3 x float> [[X]], <3 x i32> ) +; CHECK-NEXT: ret <3 x float> [[CALL]] +; +entry: + %call = tail call <3 x float> @_Z5rootnDv3_fDv3_i(<3 x float> %x, <3 x i32> ) + ret <3 x float> %call +} + +define <4 x float> @test_rootn_v4f32__y_neg1(<4 x float> %x) { +; CHECK-LABEL: define <4 x float> @test_rootn_v4f32__y_neg1( +; CHECK-SAME: <4 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <4 x float> @_Z5rootnDv4_fDv4_i(<4 x float> [[X]], <4 x i32> ) +; CHECK-NEXT: ret <4 x float> [[CALL]] +; +entry: + %call = tail call <4 x float> @_Z5rootnDv4_fDv4_i(<4 x float> %x, <4 x i32> ) + ret <4 x float> %call +} + +define <8 x float> @test_rootn_v8f32__y_neg1(<8 x float> %x) { +; CHECK-LABEL: define <8 x float> @test_rootn_v8f32__y_neg1( +; CHECK-SAME: <8 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <8 x float> @_Z5rootnDv8_fDv8_i(<8 x float> [[X]], <8 x i32> ) +; CHECK-NEXT: ret <8 x float> [[CALL]] +; +entry: + %call = tail call <8 x float> @_Z5rootnDv8_fDv8_i(<8 x float> %x, <8 x i32> ) + ret <8 x float> %call +} + +define <16 x float> @test_rootn_v16f32__y_neg1(<16 x float> %x) { +; CHECK-LABEL: define <16 x float> @test_rootn_v16f32__y_neg1( +; CHECK-SAME: <16 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <16 x float> @_Z5rootnDv16_fDv16_i(<16 x float> [[X]], <16 x i32> ) +; CHECK-NEXT: ret <16 x float> [[CALL]] +; +entry: + %call = tail call <16 x float> @_Z5rootnDv16_fDv16_i(<16 x float> %x, <16 x i32> ) + ret <16 x float> %call +} + +define float @test_rootn_f32__y_neg2(float %x) { +; CHECK-LABEL: define float @test_rootn_f32__y_neg2( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[__ROOTN2RSQRT:%.*]] = call float @_Z5rsqrtf(float [[X]]) +; CHECK-NEXT: ret float [[__ROOTN2RSQRT]] +; +entry: + %call = tail call float @_Z5rootnfi(float %x, i32 -2) + ret float %call +} + +define float @test_rootn_f32__y_neg2__flags(float %x) { +; CHECK-LABEL: define float @test_rootn_f32__y_neg2__flags( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[__ROOTN2RSQRT:%.*]] = call nnan nsz float @_Z5rsqrtf(float [[X]]) +; CHECK-NEXT: ret float [[__ROOTN2RSQRT]] +; +entry: + %call = tail call nsz nnan float @_Z5rootnfi(float %x, i32 -2) + ret float %call +} + +define float @test_rootn_f32__y_neg2__strictfp(float %x) #1 { +; CHECK-LABEL: define float @test_rootn_f32__y_neg2__strictfp( +; CHECK-SAME: float [[X:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[__ROOTN2RSQRT:%.*]] = call float @_Z5rsqrtf(float [[X]]) +; CHECK-NEXT: ret float [[__ROOTN2RSQRT]] +; +entry: + %call = tail call float @_Z5rootnfi(float %x, i32 -2) #1 + ret float %call +} + +define float @test_rootn_f32__y_neg2__noinline(float %x) { +; CHECK-LABEL: define float @test_rootn_f32__y_neg2__noinline( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[__ROOTN2RSQRT:%.*]] = call float @_Z5rsqrtf(float [[X]]) +; CHECK-NEXT: ret float [[__ROOTN2RSQRT]] +; +entry: + %call = tail call float @_Z5rootnfi(float %x, i32 -2) #2 + ret float %call +} + +define float @test_rootn_f32__y_neg2__nobuiltin(float %x) { +; CHECK-LABEL: define float @test_rootn_f32__y_neg2__nobuiltin( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 -2) #[[ATTR2:[0-9]+]] +; CHECK-NEXT: ret float [[CALL]] +; +entry: + %call = tail call float @_Z5rootnfi(float %x, i32 -2) #0 + ret float %call +} + +define <2 x float> @test_rootn_v2f32__y_neg2(<2 x float> %x) { +; CHECK-LABEL: define <2 x float> @test_rootn_v2f32__y_neg2( +; CHECK-SAME: <2 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> ) +; CHECK-NEXT: ret <2 x float> [[CALL]] +; +entry: + %call = tail call <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> %x, <2 x i32> ) + ret <2 x float> %call +} + +define <2 x float> @test_rootn_v2f32__y_neg2__flags(<2 x float> %x) { +; CHECK-LABEL: define <2 x float> @test_rootn_v2f32__y_neg2__flags( +; CHECK-SAME: <2 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call nnan nsz <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> ) +; CHECK-NEXT: ret <2 x float> [[CALL]] +; +entry: + %call = tail call nsz nnan <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> %x, <2 x i32> ) + ret <2 x float> %call +} + +define <2 x float> @test_rootn_v2f32__y_neg2__strictfp(<2 x float> %x) #1 { +; CHECK-LABEL: define <2 x float> @test_rootn_v2f32__y_neg2__strictfp( +; CHECK-SAME: <2 x float> [[X:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> ) #[[ATTR0]] +; CHECK-NEXT: ret <2 x float> [[CALL]] +; +entry: + %call = tail call <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> %x, <2 x i32> ) #1 + ret <2 x float> %call +} + +define float @test_rootn_f32__y_neg3(float %x) { +; CHECK-LABEL: define float @test_rootn_f32__y_neg3( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 -3) +; CHECK-NEXT: ret float [[CALL]] +; + %call = tail call float @_Z5rootnfi(float %x, i32 -3) + ret float %call +} + +define float @test_rootn_f32__y_neg4(float %x) { +; CHECK-LABEL: define float @test_rootn_f32__y_neg4( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 -4) +; CHECK-NEXT: ret float [[CALL]] +; + %call = tail call float @_Z5rootnfi(float %x, i32 -4) + ret float %call +} + +define float @test_rootn_afn_f32(float %x, i32 %y) { +; CHECK-LABEL: define float @test_rootn_afn_f32( +; CHECK-SAME: float [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call afn float @_Z5rootnfi(float [[X]], i32 [[Y]]) +; CHECK-NEXT: ret float [[CALL]] +; +entry: + %call = tail call afn float @_Z5rootnfi(float %x, i32 %y) + ret float %call +} + +define <2 x float> @test_rootn_afn_v2f32(<2 x float> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x float> @test_rootn_afn_v2f32( +; CHECK-SAME: <2 x float> [[X:%.*]], <2 x i32> [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call afn <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: ret <2 x float> [[CALL]] +; +entry: + %call = tail call afn <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> %x, <2 x i32> %y) + ret <2 x float> %call +} + +define double @test_rootn_afn_f64(double %x, i32 %y) { +; CHECK-LABEL: define double @test_rootn_afn_f64( +; CHECK-SAME: double [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call afn double @_Z5rootndi(double [[X]], i32 [[Y]]) +; CHECK-NEXT: ret double [[CALL]] +; +entry: + %call = tail call afn double @_Z5rootndi(double %x, i32 %y) + ret double %call +} + +define <2 x double> @test_rootn_afn_v2f64(<2 x double> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x double> @test_rootn_afn_v2f64( +; CHECK-SAME: <2 x double> [[X:%.*]], <2 x i32> [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call afn <2 x double> @_Z5rootnDv2_dDv2_i(<2 x double> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: ret <2 x double> [[CALL]] +; +entry: + %call = tail call afn <2 x double> @_Z5rootnDv2_dDv2_i(<2 x double> %x, <2 x i32> %y) + ret <2 x double> %call +} + +define half @test_rootn_afn_f16(half %x, i32 %y) { +; CHECK-LABEL: define half @test_rootn_afn_f16( +; CHECK-SAME: half [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call afn half @_Z5rootnDhi(half [[X]], i32 [[Y]]) +; CHECK-NEXT: ret half [[CALL]] +; +entry: + %call = tail call afn half @_Z5rootnDhi(half %x, i32 %y) + ret half %call +} + +define <2 x half> @test_rootn_afn_v2f16(<2 x half> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x half> @test_rootn_afn_v2f16( +; CHECK-SAME: <2 x half> [[X:%.*]], <2 x i32> [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call afn <2 x half> @_Z5rootnDv2_DhDv2_i(<2 x half> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: ret <2 x half> [[CALL]] +; +entry: + %call = tail call afn <2 x half> @_Z5rootnDv2_DhDv2_i(<2 x half> %x, <2 x i32> %y) + ret <2 x half> %call +} + +define float @test_rootn_afn_nnan_ninf_f32(float %x, i32 %y) { +; CHECK-LABEL: define float @test_rootn_afn_nnan_ninf_f32( +; CHECK-SAME: float [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn float @_Z5rootnfi(float [[X]], i32 [[Y]]) +; CHECK-NEXT: ret float [[CALL]] +; +entry: + %call = tail call nnan ninf afn float @_Z5rootnfi(float %x, i32 %y) + ret float %call +} + +define <2 x float> @test_rootn_afn_nnan_ninf_v2f32(<2 x float> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x float> @test_rootn_afn_nnan_ninf_v2f32( +; CHECK-SAME: <2 x float> [[X:%.*]], <2 x i32> [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: ret <2 x float> [[CALL]] +; +entry: + %call = tail call nnan ninf afn <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> %x, <2 x i32> %y) + ret <2 x float> %call +} + +define double @test_rootn_afn_nnan_ninf_f64(double %x, i32 %y) { +; CHECK-LABEL: define double @test_rootn_afn_nnan_ninf_f64( +; CHECK-SAME: double [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn double @_Z5rootndi(double [[X]], i32 [[Y]]) +; CHECK-NEXT: ret double [[CALL]] +; +entry: + %call = tail call nnan ninf afn double @_Z5rootndi(double %x, i32 %y) + ret double %call +} + +define <2 x double> @test_rootn_afn_nnan_ninf_v2f64(<2 x double> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x double> @test_rootn_afn_nnan_ninf_v2f64( +; CHECK-SAME: <2 x double> [[X:%.*]], <2 x i32> [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn <2 x double> @_Z5rootnDv2_dDv2_i(<2 x double> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: ret <2 x double> [[CALL]] +; +entry: + %call = tail call nnan ninf afn <2 x double> @_Z5rootnDv2_dDv2_i(<2 x double> %x, <2 x i32> %y) + ret <2 x double> %call +} + +define half @test_rootn_afn_nnan_ninf_f16(half %x, i32 %y) { +; CHECK-LABEL: define half @test_rootn_afn_nnan_ninf_f16( +; CHECK-SAME: half [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn half @_Z5rootnDhi(half [[X]], i32 [[Y]]) +; CHECK-NEXT: ret half [[CALL]] +; +entry: + %call = tail call nnan ninf afn half @_Z5rootnDhi(half %x, i32 %y) + ret half %call +} + +define <2 x half> @test_rootn_afn_nnan_ninf_v2f16(<2 x half> %x, <2 x i32> %y) { +; CHECK-LABEL: define <2 x half> @test_rootn_afn_nnan_ninf_v2f16( +; CHECK-SAME: <2 x half> [[X:%.*]], <2 x i32> [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn <2 x half> @_Z5rootnDv2_DhDv2_i(<2 x half> [[X]], <2 x i32> [[Y]]) +; CHECK-NEXT: ret <2 x half> [[CALL]] +; +entry: + %call = tail call nnan ninf afn <2 x half> @_Z5rootnDv2_DhDv2_i(<2 x half> %x, <2 x i32> %y) + ret <2 x half> %call +} + +define float @test_rootn_fast_f32_nobuiltin(float %x, i32 %y) { +; CHECK-LABEL: define float @test_rootn_fast_f32_nobuiltin( +; CHECK-SAME: float [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call fast float @_Z5rootnfi(float [[X]], i32 [[Y]]) #[[ATTR2]] +; CHECK-NEXT: ret float [[CALL]] +; +entry: + %call = tail call fast float @_Z5rootnfi(float %x, i32 %y) #0 + ret float %call +} + +define float @test_rootn_fast_f32_strictfp(float %x, i32 %y) #1 { +; CHECK-LABEL: define float @test_rootn_fast_f32_strictfp( +; CHECK-SAME: float [[X:%.*]], i32 [[Y:%.*]]) #[[ATTR0]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call fast float @_Z5rootnfi(float [[X]], i32 [[Y]]) #[[ATTR0]] +; CHECK-NEXT: ret float [[CALL]] +; +entry: + %call = tail call fast float @_Z5rootnfi(float %x, i32 %y) #1 + ret float %call +} + +define float @test_rootn_fast_f32__y_poison(float %x) { +; CHECK-LABEL: define float @test_rootn_fast_f32__y_poison( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = tail call fast float @_Z5rootnfi(float [[X]], i32 poison) +; CHECK-NEXT: ret float [[CALL]] +; + %call = tail call fast float @_Z5rootnfi(float %x, i32 poison) + ret float %call +} + +define float @test_rootn_afn_nnan_ninf_f32__y_3(float %x) { +; CHECK-LABEL: define float @test_rootn_afn_nnan_ninf_f32__y_3( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: [[__ROOTN2CBRT:%.*]] = call nnan ninf afn float @_Z4cbrtf(float [[X]]) +; CHECK-NEXT: ret float [[__ROOTN2CBRT]] +; + %call = tail call nnan ninf afn float @_Z5rootnfi(float %x, i32 3) + ret float %call +} + +define float @test_rootn_afn_nnan_ninf_f32__y_neg3(float %x) { +; CHECK-LABEL: define float @test_rootn_afn_nnan_ninf_f32__y_neg3( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn float @_Z5rootnfi(float [[X]], i32 -3) +; CHECK-NEXT: ret float [[CALL]] +; + %call = tail call nnan ninf afn float @_Z5rootnfi(float %x, i32 -3) + ret float %call +} + +define float @test_rootn_afn_nnan_ninf_f32__y_4(float %x) { +; CHECK-LABEL: define float @test_rootn_afn_nnan_ninf_f32__y_4( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn float @_Z5rootnfi(float [[X]], i32 4) +; CHECK-NEXT: ret float [[CALL]] +; + %call = tail call nnan ninf afn float @_Z5rootnfi(float %x, i32 4) + ret float %call +} + +define float @test_rootn_afn_nnan_ninf_f32__y_neg4(float %x) { +; CHECK-LABEL: define float @test_rootn_afn_nnan_ninf_f32__y_neg4( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn float @_Z5rootnfi(float [[X]], i32 -4) +; CHECK-NEXT: ret float [[CALL]] +; + %call = tail call nnan ninf afn float @_Z5rootnfi(float %x, i32 -4) + ret float %call +} + +define float @test_rootn_afn_nnan_ninf_f32__y_5(float %x) { +; CHECK-LABEL: define float @test_rootn_afn_nnan_ninf_f32__y_5( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn float @_Z5rootnfi(float [[X]], i32 5) +; CHECK-NEXT: ret float [[CALL]] +; + %call = tail call nnan ninf afn float @_Z5rootnfi(float %x, i32 5) + ret float %call +} + +define float @test_rootn_afn_nnan_ninf_f32__y_neg5(float %x) { +; CHECK-LABEL: define float @test_rootn_afn_nnan_ninf_f32__y_neg5( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn float @_Z5rootnfi(float [[X]], i32 -5) +; CHECK-NEXT: ret float [[CALL]] +; + %call = tail call nnan ninf afn float @_Z5rootnfi(float %x, i32 -5) + ret float %call +} + +define float @test_rootn_afn_nnan_ninf_f32__y_7(float %x) { +; CHECK-LABEL: define float @test_rootn_afn_nnan_ninf_f32__y_7( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn float @_Z5rootnfi(float [[X]], i32 7) +; CHECK-NEXT: ret float [[CALL]] +; + %call = tail call nnan ninf afn float @_Z5rootnfi(float %x, i32 7) + ret float %call +} + +define float @test_rootn_afn_nnan_ninf_f32__y_neg7(float %x) { +; CHECK-LABEL: define float @test_rootn_afn_nnan_ninf_f32__y_neg7( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn float @_Z5rootnfi(float [[X]], i32 -7) +; CHECK-NEXT: ret float [[CALL]] +; + %call = tail call nnan ninf afn float @_Z5rootnfi(float %x, i32 -7) + ret float %call +} + +define float @test_rootn_afn_nnan_ninf_f32__y_8(float %x) { +; CHECK-LABEL: define float @test_rootn_afn_nnan_ninf_f32__y_8( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn float @_Z5rootnfi(float [[X]], i32 8) +; CHECK-NEXT: ret float [[CALL]] +; + %call = tail call nnan ninf afn float @_Z5rootnfi(float %x, i32 8) + ret float %call +} + +define float @test_rootn_afn_nnan_ninf_f32__y_neg8(float %x) { +; CHECK-LABEL: define float @test_rootn_afn_nnan_ninf_f32__y_neg8( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn float @_Z5rootnfi(float [[X]], i32 -8) +; CHECK-NEXT: ret float [[CALL]] +; + %call = tail call nnan ninf afn float @_Z5rootnfi(float %x, i32 -8) + ret float %call +} + +define <2 x float> @test_rootn_afn_nnan_ninf_v2f32__y_3(<2 x float> %x) { +; CHECK-LABEL: define <2 x float> @test_rootn_afn_nnan_ninf_v2f32__y_3( +; CHECK-SAME: <2 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> ) +; CHECK-NEXT: ret <2 x float> [[CALL]] +; +entry: + %call = tail call afn nnan ninf <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> %x, <2 x i32> ) + ret <2 x float> %call +} + +define <2 x float> @test_rootn_afn_nnan_ninf_v2f32__y_4(<2 x float> %x) { +; CHECK-LABEL: define <2 x float> @test_rootn_afn_nnan_ninf_v2f32__y_4( +; CHECK-SAME: <2 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> ) +; CHECK-NEXT: ret <2 x float> [[CALL]] +; +entry: + %call = tail call afn nnan ninf <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> %x, <2 x i32> ) + ret <2 x float> %call +} + +define <2 x float> @test_rootn_afn_nnan_ninf_v2f32__y_neg3(<2 x float> %x) { +; CHECK-LABEL: define <2 x float> @test_rootn_afn_nnan_ninf_v2f32__y_neg3( +; CHECK-SAME: <2 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> ) +; CHECK-NEXT: ret <2 x float> [[CALL]] +; +entry: + %call = tail call afn nnan ninf <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> %x, <2 x i32> ) + ret <2 x float> %call +} + +define <2 x float> @test_rootn_afn_nnan_ninf_v2f32__y_neg4(<2 x float> %x) { +; CHECK-LABEL: define <2 x float> @test_rootn_afn_nnan_ninf_v2f32__y_neg4( +; CHECK-SAME: <2 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> ) +; CHECK-NEXT: ret <2 x float> [[CALL]] +; +entry: + %call = tail call afn nnan ninf <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> %x, <2 x i32> ) + ret <2 x float> %call +} + +define <2 x float> @test_rootn_afn_nnan_ninf_v2f32__y_5(<2 x float> %x) { +; CHECK-LABEL: define <2 x float> @test_rootn_afn_nnan_ninf_v2f32__y_5( +; CHECK-SAME: <2 x float> [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> ) +; CHECK-NEXT: ret <2 x float> [[CALL]] +; +entry: + %call = tail call afn nnan ninf <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> %x, <2 x i32> ) + ret <2 x float> %call +} + +define float @test_rootn_f32__x_known_positive(float nofpclass(ninf nsub nnorm) %x, i32 %y) { +; CHECK-LABEL: define float @test_rootn_f32__x_known_positive( +; CHECK-SAME: float nofpclass(ninf nsub nnorm) [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 [[Y]]) +; CHECK-NEXT: ret float [[CALL]] +; +entry: + %call = tail call float @_Z5rootnfi(float %x, i32 %y) + ret float %call +} + +define float @test_rootn_afn_f32__x_known_positive(float nofpclass(ninf nsub nnorm) %x, i32 %y) { +; CHECK-LABEL: define float @test_rootn_afn_f32__x_known_positive( +; CHECK-SAME: float nofpclass(ninf nsub nnorm) [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call afn float @_Z5rootnfi(float [[X]], i32 [[Y]]) +; CHECK-NEXT: ret float [[CALL]] +; +entry: + %call = tail call afn float @_Z5rootnfi(float %x, i32 %y) + ret float %call +} + +define float @test_rootn_afn_ninf_nnan_f32__x_known_positive(float nofpclass(ninf nsub nnorm) %x, i32 %y) { +; CHECK-LABEL: define float @test_rootn_afn_ninf_nnan_f32__x_known_positive( +; CHECK-SAME: float nofpclass(ninf nsub nnorm) [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn float @_Z5rootnfi(float [[X]], i32 [[Y]]) +; CHECK-NEXT: ret float [[CALL]] +; +entry: + %call = tail call afn ninf nnan float @_Z5rootnfi(float %x, i32 %y) + ret float %call +} + +define float @test_rootn_afn_f32__x_known_positive__y_4(float nofpclass(ninf nsub nnorm) %x) { +; CHECK-LABEL: define float @test_rootn_afn_f32__x_known_positive__y_4( +; CHECK-SAME: float nofpclass(ninf nsub nnorm) [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call afn float @_Z5rootnfi(float [[X]], i32 4) +; CHECK-NEXT: ret float [[CALL]] +; +entry: + %call = tail call afn float @_Z5rootnfi(float %x, i32 4) + ret float %call +} + +define float @test_rootn_f32__x_known_positive__y_4(float nofpclass(ninf nsub nnorm) %x) { +; CHECK-LABEL: define float @test_rootn_f32__x_known_positive__y_4( +; CHECK-SAME: float nofpclass(ninf nsub nnorm) [[X:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 4) +; CHECK-NEXT: ret float [[CALL]] +; +entry: + %call = tail call float @_Z5rootnfi(float %x, i32 4) + ret float %call +} + +define float @test_rootn_f32_y_known_even(float %x, i32 %y.arg) { +; CHECK-LABEL: define float @test_rootn_f32_y_known_even( +; CHECK-SAME: float [[X:%.*]], i32 [[Y_ARG:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[Y:%.*]] = shl i32 [[Y_ARG]], 1 +; CHECK-NEXT: [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 [[Y]]) +; CHECK-NEXT: ret float [[CALL]] +; +entry: + %y = shl i32 %y.arg, 1 + %call = tail call float @_Z5rootnfi(float %x, i32 %y) + ret float %call +} + +define float @test_fast_rootn_f32_y_known_even(float %x, i32 %y.arg) { +; CHECK-LABEL: define float @test_fast_rootn_f32_y_known_even( +; CHECK-SAME: float [[X:%.*]], i32 [[Y_ARG:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[Y:%.*]] = shl i32 [[Y_ARG]], 1 +; CHECK-NEXT: [[CALL:%.*]] = tail call fast float @_Z5rootnfi(float [[X]], i32 [[Y]]) +; CHECK-NEXT: ret float [[CALL]] +; +entry: + %y = shl i32 %y.arg, 1 + %call = tail call fast float @_Z5rootnfi(float %x, i32 %y) + ret float %call +} + +define float @test_fast_rootn_f32_known_positive_y_known_even(float nofpclass(ninf nsub nnorm) %x, i32 %y.arg) { +; CHECK-LABEL: define float @test_fast_rootn_f32_known_positive_y_known_even( +; CHECK-SAME: float nofpclass(ninf nsub nnorm) [[X:%.*]], i32 [[Y_ARG:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[Y:%.*]] = shl i32 [[Y_ARG]], 1 +; CHECK-NEXT: [[CALL:%.*]] = tail call fast float @_Z5rootnfi(float [[X]], i32 [[Y]]) +; CHECK-NEXT: ret float [[CALL]] +; +entry: + %y = shl i32 %y.arg, 1 + %call = tail call fast float @_Z5rootnfi(float %x, i32 %y) + ret float %call +} + +define float @test_rootn_f32__y_0_nobuiltin(float %x) { +; CHECK-LABEL: define float @test_rootn_f32__y_0_nobuiltin( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 0) #[[ATTR2]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = tail call float @_Z5rootnfi(float %x, i32 0) #0 + ret float %call +} + +define float @test_rootn_f32__y_1_nobuiltin(float %x) { +; CHECK-LABEL: define float @test_rootn_f32__y_1_nobuiltin( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 1) #[[ATTR2]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = tail call float @_Z5rootnfi(float %x, i32 1) #0 + ret float %call +} + +define float @test_rootn_f32__y_2_nobuiltin(float %x) { +; CHECK-LABEL: define float @test_rootn_f32__y_2_nobuiltin( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 2) #[[ATTR2]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = tail call float @_Z5rootnfi(float %x, i32 2) #0 + ret float %call +} + +define float @test_rootn_f32__y_3_nobuiltin(float %x) { +; CHECK-LABEL: define float @test_rootn_f32__y_3_nobuiltin( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 3) #[[ATTR2]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = tail call float @_Z5rootnfi(float %x, i32 3) #0 + ret float %call +} + +define float @test_rootn_f32__y_neg1_nobuiltin(float %x) { +; CHECK-LABEL: define float @test_rootn_f32__y_neg1_nobuiltin( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 -1) #[[ATTR2]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = tail call float @_Z5rootnfi(float %x, i32 -1) #0 + ret float %call +} + +define float @test_rootn_f32__y_neg2_nobuiltin(float %x) { +; CHECK-LABEL: define float @test_rootn_f32__y_neg2_nobuiltin( +; CHECK-SAME: float [[X:%.*]]) { +; CHECK-NEXT: [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 -2) #[[ATTR2]] +; CHECK-NEXT: ret float [[CALL]] +; + %call = tail call float @_Z5rootnfi(float %x, i32 -2) #0 + ret float %call +} + +attributes #0 = { nobuiltin } +attributes #1 = { strictfp } +attributes #2 = { noinline } + + +!0 = !{float 3.0} +;. +; CHECK: attributes #[[ATTR0]] = { strictfp } +; CHECK: attributes #[[ATTR1:[0-9]+]] = { nounwind memory(read) } +; CHECK: attributes #[[ATTR2]] = { nobuiltin } +;.