[llvm] 4a3fe8e - [AMDGPU] Gate rootn(x, +-2) -> sqrt/rsqrt fold on nsz/ninf (#200578)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 10 19:54:38 PDT 2026
Author: Arseniy Obolenskiy
Date: 2026-06-11T04:54:33+02:00
New Revision: 4a3fe8e38a6cebe805c12722b1505134d1625ce1
URL: https://github.com/llvm/llvm-project/commit/4a3fe8e38a6cebe805c12722b1505134d1625ce1
DIFF: https://github.com/llvm/llvm-project/commit/4a3fe8e38a6cebe805c12722b1505134d1625ce1.diff
LOG: [AMDGPU] Gate rootn(x, +-2) -> sqrt/rsqrt fold on nsz/ninf (#200578)
Added:
Modified:
llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-rootn-fast.ll
llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-rootn.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp b/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
index 1e92028b0fff3..2d1cc1c0c66c0 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
@@ -1169,7 +1169,12 @@ bool AMDGPULibCalls::fold_rootn(FPMathOperator *FPOp, IRBuilder<> &B,
Module *M = B.GetInsertBlock()->getModule();
CallInst *CI = cast<CallInst>(FPOp);
- if (ci_opr1 == 2 &&
+
+ // rootn and sqrt disagree on signed-zero / -Inf inputs (e.g. rootn(-0.0, 2)
+ // is +0.0, sqrt(-0.0) is -0.0), so require nsz/ninf.
+ bool FMFOkForSqrt = FPOp->hasNoSignedZeros() && FPOp->hasNoInfs();
+
+ if (ci_opr1 == 2 && FMFOkForSqrt &&
shouldReplaceLibcallWithIntrinsic(CI,
/*AllowMinSizeF32=*/true,
/*AllowF64=*/true)) {
@@ -1208,7 +1213,7 @@ bool AMDGPULibCalls::fold_rootn(FPMathOperator *FPOp, IRBuilder<> &B,
return true;
}
- if (ci_opr1 == -2 &&
+ if (ci_opr1 == -2 && FMFOkForSqrt &&
shouldReplaceLibcallWithIntrinsic(CI,
/*AllowMinSizeF32=*/true,
/*AllowF64=*/true)) {
diff --git a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-rootn-fast.ll b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-rootn-fast.ll
index 812f56a8d6f64..e3c852b58f9bb 100644
--- a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-rootn-fast.ll
+++ b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-rootn-fast.ll
@@ -89,7 +89,7 @@ define float @test_rootn_afn_f32__2(float %x) #0 {
; CHECK-LABEL: define float @test_rootn_afn_f32__2(
; CHECK-SAME: float [[X:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[CALL:%.*]] = call afn float @llvm.sqrt.f32(float [[X]]), !fpmath [[META0:![0-9]+]]
+; CHECK-NEXT: [[CALL:%.*]] = tail call afn float @_Z12__rootn_fastfi(float [[X]], i32 2)
; CHECK-NEXT: ret float [[CALL]]
;
entry:
@@ -125,8 +125,7 @@ define float @test_rootn_afn_f32__neg2(float %x) #0 {
; CHECK-LABEL: define float @test_rootn_afn_f32__neg2(
; CHECK-SAME: float [[X:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[TMP0:%.*]] = call contract afn float @llvm.sqrt.f32(float [[X]])
-; CHECK-NEXT: [[TMP1:%.*]] = fdiv contract afn float 1.000000e+00, [[TMP0]], !fpmath [[META0]]
+; CHECK-NEXT: [[TMP1:%.*]] = tail call afn float @_Z12__rootn_fastfi(float [[X]], i32 -2)
; CHECK-NEXT: ret float [[TMP1]]
;
entry:
@@ -134,11 +133,23 @@ entry:
ret float %call
}
+define float @test_rootn_afn_f32__2_nsz_ninf(float %x) #0 {
+; CHECK-LABEL: define float @test_rootn_afn_f32__2_nsz_ninf(
+; CHECK-SAME: float [[X:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[CALL:%.*]] = call ninf nsz afn float @llvm.sqrt.f32(float [[X]]), !fpmath [[META0:![0-9]+]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+entry:
+ %call = tail call afn nsz ninf float @_Z5rootnfi(float %x, i32 2)
+ ret float %call
+}
+
define <2 x float> @test_rootn_afn_v2f32__2(<2 x float> %x) #0 {
; CHECK-LABEL: define <2 x float> @test_rootn_afn_v2f32__2(
; CHECK-SAME: <2 x float> [[X:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[CALL:%.*]] = call afn <2 x float> @llvm.sqrt.v2f32(<2 x float> [[X]]), !fpmath [[META0]]
+; CHECK-NEXT: [[CALL:%.*]] = tail call afn <2 x float> @_Z12__rootn_fastDv2_fDv2_i(<2 x float> [[X]], <2 x i32> splat (i32 2))
; CHECK-NEXT: ret <2 x float> [[CALL]]
;
entry:
@@ -174,8 +185,7 @@ define <2 x float> @test_rootn_afn_v2f32__neg2(<2 x float> %x) #0 {
; CHECK-LABEL: define <2 x float> @test_rootn_afn_v2f32__neg2(
; CHECK-SAME: <2 x float> [[X:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[TMP0:%.*]] = call contract afn <2 x float> @llvm.sqrt.v2f32(<2 x float> [[X]])
-; CHECK-NEXT: [[TMP1:%.*]] = fdiv contract afn <2 x float> splat (float 1.000000e+00), [[TMP0]], !fpmath [[META0]]
+; CHECK-NEXT: [[TMP1:%.*]] = tail call afn <2 x float> @_Z12__rootn_fastDv2_fDv2_i(<2 x float> [[X]], <2 x i32> splat (i32 -2))
; CHECK-NEXT: ret <2 x float> [[TMP1]]
;
entry:
@@ -293,7 +303,7 @@ define float @test__rootn_fast_f32__2(float %x) #0 {
; CHECK-LABEL: define float @test__rootn_fast_f32__2(
; CHECK-SAME: float [[X:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.sqrt.f32(float [[X]]), !fpmath [[META0]]
+; CHECK-NEXT: [[CALL:%.*]] = tail call float @_Z12__rootn_fastfi(float [[X]], i32 2)
; CHECK-NEXT: ret float [[CALL]]
;
entry:
@@ -305,7 +315,7 @@ define float @test__rootn_fast_afn_f32__2(float %x) #0 {
; CHECK-LABEL: define float @test__rootn_fast_afn_f32__2(
; CHECK-SAME: float [[X:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[CALL:%.*]] = call afn float @llvm.sqrt.f32(float [[X]]), !fpmath [[META0]]
+; CHECK-NEXT: [[CALL:%.*]] = tail call afn float @_Z12__rootn_fastfi(float [[X]], i32 2)
; CHECK-NEXT: ret float [[CALL]]
;
entry:
@@ -365,8 +375,7 @@ define float @test__rootn_fast_f32__neg2(float %x) #0 {
; CHECK-LABEL: define float @test__rootn_fast_f32__neg2(
; CHECK-SAME: float [[X:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[TMP0:%.*]] = call contract float @llvm.sqrt.f32(float [[X]])
-; CHECK-NEXT: [[TMP1:%.*]] = fdiv contract float 1.000000e+00, [[TMP0]], !fpmath [[META0]]
+; CHECK-NEXT: [[TMP1:%.*]] = tail call float @_Z12__rootn_fastfi(float [[X]], i32 -2)
; CHECK-NEXT: ret float [[TMP1]]
;
entry:
@@ -378,8 +387,7 @@ define float @test__rootn_fast_afn_f32__neg2(float %x) #0 {
; CHECK-LABEL: define float @test__rootn_fast_afn_f32__neg2(
; CHECK-SAME: float [[X:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[TMP0:%.*]] = call contract afn float @llvm.sqrt.f32(float [[X]])
-; CHECK-NEXT: [[TMP1:%.*]] = fdiv contract afn float 1.000000e+00, [[TMP0]], !fpmath [[META0]]
+; CHECK-NEXT: [[TMP1:%.*]] = tail call afn float @_Z12__rootn_fastfi(float [[X]], i32 -2)
; CHECK-NEXT: ret float [[TMP1]]
;
entry:
diff --git a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-rootn.ll b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-rootn.ll
index 83c8d10425883..4f0faef4486a6 100644
--- a/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-rootn.ll
+++ b/llvm/test/CodeGen/AMDGPU/amdgpu-simplify-libcall-rootn.ll
@@ -271,7 +271,7 @@ define half @test_rootn_f16_1(half %x) {
define half @test_rootn_f16_2(half %x) {
; CHECK-LABEL: define half @test_rootn_f16_2(
; CHECK-SAME: half [[X:%.*]]) {
-; CHECK-NEXT: [[CALL:%.*]] = call half @llvm.sqrt.f16(half [[X]]), !fpmath [[META1:![0-9]+]]
+; CHECK-NEXT: [[CALL:%.*]] = tail call half @_Z5rootnDhi(half [[X]], i32 2)
; CHECK-NEXT: ret half [[CALL]]
;
%call = tail call half @_Z5rootnDhi(half %x, i32 2)
@@ -306,8 +306,7 @@ define half @test_rootn_f16_neg1(half %x) {
define half @test_rootn_f16_neg2(half %x) {
; CHECK-LABEL: define half @test_rootn_f16_neg2(
; CHECK-SAME: half [[X:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call contract half @llvm.sqrt.f16(half [[X]])
-; CHECK-NEXT: [[__ROOTN2RSQRT:%.*]] = fdiv contract half 1.000000e+00, [[TMP1]], !fpmath [[META1]]
+; CHECK-NEXT: [[__ROOTN2RSQRT:%.*]] = tail call half @_Z5rootnDhi(half [[X]], i32 -2)
; CHECK-NEXT: ret half [[__ROOTN2RSQRT]]
;
%call = tail call half @_Z5rootnDhi(half %x, i32 -2)
@@ -356,7 +355,7 @@ define <2 x half> @test_rootn_v2f16_1(<2 x half> %x) {
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:%.*]] = call <2 x half> @llvm.sqrt.v2f16(<2 x half> [[X]]), !fpmath [[META1]]
+; CHECK-NEXT: [[CALL:%.*]] = tail call <2 x half> @_Z5rootnDv2_DhDv2_i(<2 x half> [[X]], <2 x i32> splat (i32 2))
; CHECK-NEXT: ret <2 x half> [[CALL]]
;
%call = tail call <2 x half> @_Z5rootnDv2_DhDv2_i(<2 x half> %x, <2 x i32> <i32 2, i32 2>)
@@ -376,8 +375,7 @@ define <2 x half> @test_rootn_v2f16_neg1(<2 x half> %x) {
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: [[TMP1:%.*]] = call contract <2 x half> @llvm.sqrt.v2f16(<2 x half> [[X]])
-; CHECK-NEXT: [[__ROOTN2RSQRT:%.*]] = fdiv contract <2 x half> splat (half 1.000000e+00), [[TMP1]], !fpmath [[META1]]
+; CHECK-NEXT: [[__ROOTN2RSQRT:%.*]] = tail call <2 x half> @_Z5rootnDv2_DhDv2_i(<2 x half> [[X]], <2 x i32> splat (i32 -2))
; CHECK-NEXT: ret <2 x half> [[__ROOTN2RSQRT]]
;
%call = tail call <2 x half> @_Z5rootnDv2_DhDv2_i(<2 x half> %x, <2 x i32> <i32 -2, i32 -2>)
@@ -618,7 +616,7 @@ 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: [[CALL:%.*]] = call float @llvm.sqrt.f32(float [[X]]), !fpmath [[META1]]
+; CHECK-NEXT: [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 2)
; CHECK-NEXT: ret float [[CALL]]
;
entry:
@@ -630,7 +628,7 @@ 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: [[CALL:%.*]] = call nnan nsz float @llvm.sqrt.f32(float [[X]]), !fpmath [[META1]]
+; CHECK-NEXT: [[CALL:%.*]] = tail call nnan nsz float @_Z5rootnfi(float [[X]], i32 2)
; CHECK-NEXT: ret float [[CALL]]
;
entry:
@@ -638,12 +636,26 @@ entry:
ret float %call
}
+; nsz+ninf are required to legalize the rootn(-0.0,2)/rootn(-Inf,2) corners,
+; so the fold should fire here.
+define float @test_rootn_f32__y_2_nsz_ninf(float %x) {
+; CHECK-LABEL: define float @test_rootn_f32__y_2_nsz_ninf(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[CALL:%.*]] = call ninf nsz float @llvm.sqrt.f32(float [[X]]), !fpmath [[META1:![0-9]+]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+entry:
+ %call = tail call nsz ninf 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: [[CALL:%.*]] = call nnan nsz float @llvm.sqrt.f32(float [[X]]), !fpmath [[META2:![0-9]+]]
+; CHECK-NEXT: [[CALL:%.*]] = tail call nnan nsz float @_Z5rootnfi(float [[X]], i32 2), !fpmath [[META2:![0-9]+]]
; CHECK-NEXT: ret float [[CALL]]
;
entry:
@@ -655,7 +667,7 @@ 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:%.*]] = call nnan nsz <2 x float> @llvm.sqrt.v2f32(<2 x float> [[X]]), !fpmath [[META1]]
+; CHECK-NEXT: [[CALL:%.*]] = tail call nnan nsz <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> splat (i32 2))
; CHECK-NEXT: ret <2 x float> [[CALL]]
;
entry:
@@ -667,7 +679,7 @@ 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:%.*]] = call <3 x float> @llvm.sqrt.v3f32(<3 x float> [[X]]), !fpmath [[META1]]
+; CHECK-NEXT: [[CALL:%.*]] = tail call <3 x float> @_Z5rootnDv3_fDv3_i(<3 x float> [[X]], <3 x i32> splat (i32 2))
; CHECK-NEXT: ret <3 x float> [[CALL]]
;
entry:
@@ -679,7 +691,7 @@ 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:%.*]] = call <3 x float> @llvm.sqrt.v3f32(<3 x float> [[X]]), !fpmath [[META1]]
+; CHECK-NEXT: [[CALL:%.*]] = tail call <3 x float> @_Z5rootnDv3_fDv3_i(<3 x float> [[X]], <3 x i32> <i32 2, i32 poison, i32 2>)
; CHECK-NEXT: ret <3 x float> [[CALL]]
;
entry:
@@ -691,7 +703,7 @@ 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:%.*]] = call <4 x float> @llvm.sqrt.v4f32(<4 x float> [[X]]), !fpmath [[META1]]
+; CHECK-NEXT: [[CALL:%.*]] = tail call <4 x float> @_Z5rootnDv4_fDv4_i(<4 x float> [[X]], <4 x i32> splat (i32 2))
; CHECK-NEXT: ret <4 x float> [[CALL]]
;
entry:
@@ -703,7 +715,7 @@ 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:%.*]] = call <8 x float> @llvm.sqrt.v8f32(<8 x float> [[X]]), !fpmath [[META1]]
+; CHECK-NEXT: [[CALL:%.*]] = tail call <8 x float> @_Z5rootnDv8_fDv8_i(<8 x float> [[X]], <8 x i32> splat (i32 2))
; CHECK-NEXT: ret <8 x float> [[CALL]]
;
entry:
@@ -715,7 +727,7 @@ 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:%.*]] = call <16 x float> @llvm.sqrt.v16f32(<16 x float> [[X]]), !fpmath [[META1]]
+; CHECK-NEXT: [[CALL:%.*]] = tail call <16 x float> @_Z5rootnDv16_fDv16_i(<16 x float> [[X]], <16 x i32> splat (i32 2))
; CHECK-NEXT: ret <16 x float> [[CALL]]
;
entry:
@@ -775,7 +787,7 @@ 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:%.*]] = call <2 x float> @llvm.sqrt.v2f32(<2 x float> [[X]]), !fpmath [[META1]]
+; CHECK-NEXT: [[CALL:%.*]] = tail call <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> <i32 2, i32 poison>)
; CHECK-NEXT: ret <2 x float> [[CALL]]
;
entry:
@@ -883,8 +895,7 @@ 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: [[TMP0:%.*]] = call contract float @llvm.sqrt.f32(float [[X]])
-; CHECK-NEXT: [[__ROOTN2RSQRT:%.*]] = fdiv contract float 1.000000e+00, [[TMP0]], !fpmath [[META1]]
+; CHECK-NEXT: [[__ROOTN2RSQRT:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 -2)
; CHECK-NEXT: ret float [[__ROOTN2RSQRT]]
;
entry:
@@ -896,8 +907,7 @@ 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: [[TMP0:%.*]] = call nnan nsz contract float @llvm.sqrt.f32(float [[X]])
-; CHECK-NEXT: [[__ROOTN2RSQRT:%.*]] = fdiv nnan nsz contract float 1.000000e+00, [[TMP0]], !fpmath [[META1]]
+; CHECK-NEXT: [[__ROOTN2RSQRT:%.*]] = tail call nnan nsz float @_Z5rootnfi(float [[X]], i32 -2)
; CHECK-NEXT: ret float [[__ROOTN2RSQRT]]
;
entry:
@@ -905,6 +915,21 @@ entry:
ret float %call
}
+; nsz+ninf are required to legalize the rootn(-0.0,-2)/rootn(-Inf,-2)
+; corners, so the rsqrt fold should fire here.
+define float @test_rootn_f32__y_neg2__nsz_ninf(float %x) {
+; CHECK-LABEL: define float @test_rootn_f32__y_neg2__nsz_ninf(
+; CHECK-SAME: float [[X:%.*]]) {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP0:%.*]] = call ninf nsz contract float @llvm.sqrt.f32(float [[X]])
+; CHECK-NEXT: [[TMP1:%.*]] = fdiv ninf nsz contract float 1.000000e+00, [[TMP0]], !fpmath [[META1]]
+; CHECK-NEXT: ret float [[TMP1]]
+;
+entry:
+ %call = tail call nsz ninf 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]] {
@@ -921,8 +946,8 @@ 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:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 -2) #[[ATTR3:[0-9]+]]
-; CHECK-NEXT: ret float [[__ROOTN2RSQRT]]
+; CHECK-NEXT: [[CALL:%.*]] = tail call float @_Z5rootnfi(float [[X]], i32 -2) #[[ATTR3:[0-9]+]]
+; CHECK-NEXT: ret float [[CALL]]
;
entry:
%call = tail call float @_Z5rootnfi(float %x, i32 -2) #2
@@ -945,8 +970,7 @@ 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: [[TMP0:%.*]] = call contract <2 x float> @llvm.sqrt.v2f32(<2 x float> [[X]])
-; CHECK-NEXT: [[__ROOTN2RSQRT:%.*]] = fdiv contract <2 x float> splat (float 1.000000e+00), [[TMP0]], !fpmath [[META1]]
+; CHECK-NEXT: [[__ROOTN2RSQRT:%.*]] = tail call <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> splat (i32 -2))
; CHECK-NEXT: ret <2 x float> [[__ROOTN2RSQRT]]
;
entry:
@@ -958,8 +982,7 @@ 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: [[TMP0:%.*]] = call nnan nsz contract <2 x float> @llvm.sqrt.v2f32(<2 x float> [[X]])
-; CHECK-NEXT: [[__ROOTN2RSQRT:%.*]] = fdiv nnan nsz contract <2 x float> splat (float 1.000000e+00), [[TMP0]], !fpmath [[META1]]
+; CHECK-NEXT: [[__ROOTN2RSQRT:%.*]] = tail call nnan nsz <2 x float> @_Z5rootnDv2_fDv2_i(<2 x float> [[X]], <2 x i32> splat (i32 -2))
; CHECK-NEXT: ret <2 x float> [[__ROOTN2RSQRT]]
;
entry:
@@ -1955,8 +1978,8 @@ attributes #2 = { noinline }
;.
; PRELINK: attributes #[[ATTR0]] = { strictfp }
-; PRELINK: attributes #[[ATTR1:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
-; PRELINK: attributes #[[ATTR2:[0-9]+]] = { nounwind memory(read) }
+; PRELINK: attributes #[[ATTR1:[0-9]+]] = { nounwind memory(read) }
+; PRELINK: attributes #[[ATTR2:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
; PRELINK: attributes #[[ATTR3]] = { noinline }
; PRELINK: attributes #[[ATTR4]] = { nobuiltin }
;.
More information about the llvm-commits
mailing list