diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp --- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -1668,10 +1668,6 @@ bool AllowApprox = Pow->hasApproxFunc(); bool Ignored; - // Bail out if simplifying libcalls to pow() is disabled. - if (!hasFloatFn(TLI, Ty, LibFunc_pow, LibFunc_powf, LibFunc_powl)) - return nullptr; - // Propagate the math semantics from the call to any created instructions. IRBuilderBase::FastMathFlagGuard Guard(B); B.setFastMathFlags(Pow->getFastMathFlags()); diff --git a/llvm/test/Transforms/InstCombine/pow-1.ll b/llvm/test/Transforms/InstCombine/pow-1.ll --- a/llvm/test/Transforms/InstCombine/pow-1.ll +++ b/llvm/test/Transforms/InstCombine/pow-1.ll @@ -1,18 +1,19 @@ ; Test that the pow library call simplifier works correctly. ; -; RUN: opt -instcombine -S < %s | FileCheck %s --check-prefixes=CHECK,ANY -; RUN: opt -instcombine -S < %s -mtriple=x86_64-apple-macosx10.9 | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-EXP10 -; RUN: opt -instcombine -S < %s -mtriple=arm-apple-ios7.0 | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-EXP10 -; RUN: opt -instcombine -S < %s -mtriple=x86_64-apple-macosx10.8 | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-NO-EXP10 -; RUN: opt -instcombine -S < %s -mtriple=arm-apple-ios6.0 | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-NO-EXP10 -; RUN: opt -instcombine -S < %s -mtriple=x86_64-netbsd | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-NO-EXP10 -; RUN: opt -instcombine -S < %s -mtriple=arm-apple-tvos9.0 | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-EXP10 -; RUN: opt -instcombine -S < %s -mtriple=arm-apple-watchos2.0 | FileCheck %s --check-prefixes=CHECK,ANY,CHECK-EXP10 +; RUN: opt -instcombine -S < %s | FileCheck %s --check-prefixes=CHECK,LIB,ANY +; RUN: opt -instcombine -S < %s -mtriple=x86_64-apple-macosx10.9 | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-EXP10 +; RUN: opt -instcombine -S < %s -mtriple=arm-apple-ios7.0 | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-EXP10 +; RUN: opt -instcombine -S < %s -mtriple=x86_64-apple-macosx10.8 | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-NO-EXP10 +; RUN: opt -instcombine -S < %s -mtriple=arm-apple-ios6.0 | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-NO-EXP10 +; RUN: opt -instcombine -S < %s -mtriple=x86_64-netbsd | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-NO-EXP10 +; RUN: opt -instcombine -S < %s -mtriple=arm-apple-tvos9.0 | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-EXP10 +; RUN: opt -instcombine -S < %s -mtriple=arm-apple-watchos2.0 | FileCheck %s --check-prefixes=CHECK,LIB,ANY,CHECK-EXP10 ; rdar://7251832 -; RUN: opt -instcombine -S < %s -mtriple=i386-pc-windows-msvc18 | FileCheck %s --check-prefixes=CHECK,MSVC,VC32,CHECK-NO-EXP10 -; RUN: opt -instcombine -S < %s -mtriple=i386-pc-windows-msvc | FileCheck %s --check-prefixes=CHECK,MSVC,VC51,VC19,CHECK-NO-EXP10 -; RUN: opt -instcombine -S < %s -mtriple=x86_64-pc-windows-msvc18 | FileCheck %s --check-prefixes=CHECK,MSVC,VC64,CHECK-NO-EXP10 -; RUN: opt -instcombine -S < %s -mtriple=x86_64-pc-windows-msvc | FileCheck %s --check-prefixes=CHECK,MSVC,VC83,VC19,CHECK-NO-EXP10 +; RUN: opt -instcombine -S < %s -mtriple=i386-pc-windows-msvc18 | FileCheck %s --check-prefixes=CHECK,LIB,MSVC,VC32,CHECK-NO-EXP10 +; RUN: opt -instcombine -S < %s -mtriple=i386-pc-windows-msvc | FileCheck %s --check-prefixes=CHECK,LIB,MSVC,VC51,VC19,CHECK-NO-EXP10 +; RUN: opt -instcombine -S < %s -mtriple=x86_64-pc-windows-msvc18 | FileCheck %s --check-prefixes=CHECK,LIB,MSVC,VC64,CHECK-NO-EXP10 +; RUN: opt -instcombine -S < %s -mtriple=x86_64-pc-windows-msvc | FileCheck %s --check-prefixes=CHECK,LIB,MSVC,VC83,VC19,CHECK-NO-EXP10 +; RUN: opt -instcombine -S < %s -mtriple=amdgcn-- | FileCheck %s --check-prefixes=CHECK,NOLIB ; NOTE: The readonly attribute on the pow call should be preserved ; in the cases below where pow is transformed into another function call. @@ -31,6 +32,8 @@ ; VC32-NEXT: [[POW:%.*]] = call float @powf(float 1.000000e+00, float [[X:%.*]]) ; VC32-NEXT: ret float [[POW]] ; VC64-NEXT: ret float 1.000000e+00 +; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float 1.000000e+00, float [[X:%.*]]) +; NOLIB-NEXT: ret float [[RETVAL]] ; %retval = call float @powf(float 1.0, float %x) ret float %retval @@ -38,9 +41,7 @@ define <2 x float> @test_simplify1v(<2 x float> %x) { ; CHECK-LABEL: @test_simplify1v( -; ANY-NEXT: ret <2 x float> -; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> , <2 x float> [[X:%.*]]) -; MSVC-NEXT: ret <2 x float> [[POW]] +; CHECK-NEXT: ret <2 x float> ; %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> , <2 x float> %x) ret <2 x float> %retval @@ -48,7 +49,9 @@ define double @test_simplify2(double %x) { ; CHECK-LABEL: @test_simplify2( -; CHECK-NEXT: ret double 1.000000e+00 +; LIB-NEXT: ret double 1.000000e+00 +; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double 1.000000e+00, double [[X:%.*]]) +; NOLIB-NEXT: ret double [[RETVAL]] ; %retval = call double @pow(double 1.0, double %x) ret double %retval @@ -56,9 +59,7 @@ define <2 x double> @test_simplify2v(<2 x double> %x) { ; CHECK-LABEL: @test_simplify2v( -; ANY-NEXT: ret <2 x double> -; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> , <2 x double> [[X:%.*]]) -; MSVC-NEXT: ret <2 x double> [[POW]] +; CHECK-NEXT: ret <2 x double> ; %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> , <2 x double> %x) ret <2 x double> %retval @@ -78,6 +79,8 @@ ; VC64-NEXT: ret float [[POW]] ; VC83-NEXT: [[EXP2F:%.*]] = call float @exp2f(float [[X:%.*]]) ; VC83-NEXT: ret float [[EXP2F]] +; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float 2.000000e+00, float [[X:%.*]]) +; NOLIB-NEXT: ret float [[RETVAL]] ; %retval = call float @powf(float 2.0, float %x) ret float %retval @@ -95,6 +98,8 @@ ; VC32-NEXT: ret double [[POW]] ; VC64-NEXT: [[POW:%.*]] = call double @pow(double 2.500000e-01, double [[X:%.*]]) ; VC64-NEXT: ret double [[POW]] +; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double 2.500000e-01, double [[X:%.*]]) +; NOLIB-NEXT: ret double [[RETVAL]] ; %retval = call double @pow(double 0.25, double %x) ret double %retval @@ -106,6 +111,9 @@ ; ANY-NEXT: ret <2 x float> [[EXP2]] ; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> , <2 x float> [[X:%.*]]) ; MSVC-NEXT: ret <2 x float> [[POW]] +; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls +; NOLIB-NEXT: [[RETVAL:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> , <2 x float> [[X:%.*]]) +; NOLIB-NEXT: ret <2 x float> [[RETVAL]] ; %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> , <2 x float> %x) ret <2 x float> %retval @@ -118,6 +126,9 @@ ; ANY-NEXT: ret <2 x double> [[EXP2]] ; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> , <2 x double> [[X:%.*]]) ; MSVC-NEXT: ret <2 x double> [[POW]] +; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls +; NOLIB-NEXT: [[RETVAL:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> , <2 x double> [[X:%.*]]) +; NOLIB-NEXT: ret <2 x double> [[RETVAL]] ; %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> , <2 x double> %x) ret <2 x double> %retval @@ -133,6 +144,8 @@ ; VC32-NEXT: ret double [[POW]] ; VC64-NEXT: [[POW:%.*]] = call double @pow(double 2.000000e+00, double [[X:%.*]]) ; VC64-NEXT: ret double [[POW]] +; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double 2.000000e+00, double [[X:%.*]]) +; NOLIB-NEXT: ret double [[RETVAL]] ; %retval = call double @pow(double 2.0, double %x) ret double %retval @@ -152,6 +165,8 @@ ; VC83-NEXT: [[MUL:%.*]] = fmul float [[X:%.*]], 3.000000e+00 ; VC83-NEXT: [[EXP2F:%.*]] = call float @exp2f(float [[MUL]]) ; VC83-NEXT: ret float [[EXP2F]] +; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float 8.000000e+00, float [[X:%.*]]) +; NOLIB-NEXT: ret float [[RETVAL]] ; %retval = call float @powf(float 8.0, float %x) ret float %retval @@ -163,6 +178,9 @@ ; ANY-NEXT: ret <2 x double> [[EXP2]] ; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> , <2 x double> [[X:%.*]]) ; MSVC-NEXT: ret <2 x double> [[POW]] +; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls +; NOLIB-NEXT: [[RETVAL:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> , <2 x double> [[X:%.*]]) +; NOLIB-NEXT: ret <2 x double> [[RETVAL]] ; %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> , <2 x double> %x) ret <2 x double> %retval @@ -175,6 +193,9 @@ ; ANY-NEXT: ret <2 x float> [[EXP2]] ; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> , <2 x float> [[X:%.*]]) ; MSVC-NEXT: ret <2 x float> [[POW]] +; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls +; NOLIB-NEXT: [[RETVAL:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> , <2 x float> [[X:%.*]]) +; NOLIB-NEXT: ret <2 x float> [[RETVAL]] ; %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> , <2 x float> %x) ret <2 x float> %retval @@ -191,6 +212,8 @@ ; VC51-NEXT: ret float [[POW]] ; VC64-NEXT: ret float 1.000000e+00 ; VC83-NEXT: ret float 1.000000e+00 +; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X:%.*]], float 0.000000e+00) +; NOLIB-NEXT: ret float [[RETVAL]] ; %retval = call float @powf(float %x, float 0.0) ret float %retval @@ -198,9 +221,7 @@ define <2 x float> @test_simplify5v(<2 x float> %x) { ; CHECK-LABEL: @test_simplify5v( -; ANY-NEXT: ret <2 x float> -; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> zeroinitializer) -; MSVC-NEXT: ret <2 x float> [[POW]] +; CHECK-NEXT: ret <2 x float> ; %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> ) ret <2 x float> %retval @@ -208,7 +229,9 @@ define double @test_simplify6(double %x) { ; CHECK-LABEL: @test_simplify6( -; CHECK-NEXT: ret double 1.000000e+00 +; LIB-NEXT: ret double 1.000000e+00 +; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double [[X:%.*]], double 0.000000e+00) +; NOLIB-NEXT: ret double [[RETVAL]] ; %retval = call double @pow(double %x, double 0.0) ret double %retval @@ -216,9 +239,7 @@ define <2 x double> @test_simplify6v(<2 x double> %x) { ; CHECK-LABEL: @test_simplify6v( -; ANY-NEXT: ret <2 x double> -; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> zeroinitializer) -; MSVC-NEXT: ret <2 x double> [[POW]] +; CHECK-NEXT: ret <2 x double> ; %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> ) ret <2 x double> %retval @@ -247,6 +268,8 @@ ; VC83-NEXT: [[ISINF:%.*]] = fcmp oeq float [[X]], 0xFFF0000000000000 ; VC83-NEXT: [[TMP1:%.*]] = select i1 [[ISINF]], float 0x7FF0000000000000, float [[ABS]] ; VC83-NEXT: ret float [[TMP1]] +; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X:%.*]], float 5.000000e-01) +; NOLIB-NEXT: ret float [[RETVAL]] ; %retval = call float @powf(float %x, float 0.5) ret float %retval @@ -254,11 +277,13 @@ define double @test_simplify8(double %x) { ; CHECK-LABEL: @test_simplify8( -; CHECK-NEXT: [[SQRT:%.*]] = call double @sqrt(double [[X:%.*]]) -; CHECK-NEXT: [[ABS:%.*]] = call double @llvm.fabs.f64(double [[SQRT]]) -; CHECK-NEXT: [[ISINF:%.*]] = fcmp oeq double [[X]], 0xFFF0000000000000 -; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[ISINF]], double 0x7FF0000000000000, double [[ABS]] -; CHECK-NEXT: ret double [[TMP1]] +; LIB-NEXT: [[SQRT:%.*]] = call double @sqrt(double [[X:%.*]]) +; LIB-NEXT: [[ABS:%.*]] = call double @llvm.fabs.f64(double [[SQRT]]) +; LIB-NEXT: [[ISINF:%.*]] = fcmp oeq double [[X]], 0xFFF0000000000000 +; LIB-NEXT: [[TMP1:%.*]] = select i1 [[ISINF]], double 0x7FF0000000000000, double [[ABS]] +; LIB-NEXT: ret double [[TMP1]] +; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double [[X:%.*]], double 5.000000e-01) +; NOLIB-NEXT: ret double [[RETVAL]] ; %retval = call double @pow(double %x, double 0.5) ret double %retval @@ -275,6 +300,8 @@ ; VC51-NEXT: ret float [[POW]] ; VC64-NEXT: ret float 0x7FF0000000000000 ; VC83-NEXT: ret float 0x7FF0000000000000 +; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float 0xFFF0000000000000, float 5.000000e-01) +; NOLIB-NEXT: ret float [[RETVAL]] ; %retval = call float @powf(float 0xFFF0000000000000, float 0.5) ret float %retval @@ -282,7 +309,9 @@ define double @test_simplify10(double %x) { ; CHECK-LABEL: @test_simplify10( -; CHECK-NEXT: ret double 0x7FF0000000000000 +; LIB-NEXT: ret double 0x7FF0000000000000 +; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double 0xFFF0000000000000, double 5.000000e-01) +; NOLIB-NEXT: ret double [[RETVAL]] ; %retval = call double @pow(double 0xFFF0000000000000, double 0.5) ret double %retval @@ -299,6 +328,8 @@ ; VC51-NEXT: ret float [[POW]] ; VC64-NEXT: ret float [[X:%.*]] ; VC83-NEXT: ret float [[X:%.*]] +; NOLIB-NEXT: [[RETVAL:%.*]] = call float @powf(float [[X:%.*]], float 1.000000e+00) +; NOLIB-NEXT: ret float [[RETVAL]] ; %retval = call float @powf(float %x, float 1.0) ret float %retval @@ -306,9 +337,7 @@ define <2 x float> @test_simplify11v(<2 x float> %x) { ; CHECK-LABEL: @test_simplify11v( -; ANY-NEXT: ret <2 x float> [[X:%.*]] -; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> ) -; MSVC-NEXT: ret <2 x float> [[POW]] +; CHECK-NEXT: ret <2 x float> [[X:%.*]] ; %retval = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> ) ret <2 x float> %retval @@ -316,7 +345,9 @@ define double @test_simplify12(double %x) { ; CHECK-LABEL: @test_simplify12( -; CHECK-NEXT: ret double [[X:%.*]] +; LIB-NEXT: ret double [[X:%.*]] +; NOLIB-NEXT: [[RETVAL:%.*]] = call double @pow(double [[X:%.*]], double 1.000000e+00) +; NOLIB-NEXT: ret double [[RETVAL]] ; %retval = call double @pow(double %x, double 1.0) ret double %retval @@ -324,9 +355,7 @@ define <2 x double> @test_simplify12v(<2 x double> %x) { ; CHECK-LABEL: @test_simplify12v( -; ANY-NEXT: ret <2 x double> [[X:%.*]] -; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> ) -; MSVC-NEXT: ret <2 x double> [[POW]] +; CHECK-NEXT: ret <2 x double> [[X:%.*]] ; %retval = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> ) ret <2 x double> %retval @@ -346,6 +375,8 @@ ; VC64-NEXT: ret float [[SQUARE]] ; VC83-NEXT: [[SQUARE:%.*]] = fmul float [[X:%.*]], [[X]] ; VC83-NEXT: ret float [[SQUARE]] +; NOLIB-NEXT: [[R:%.*]] = call float @powf(float [[X:%.*]], float 2.000000e+00) +; NOLIB-NEXT: ret float [[R]] ; %r = call float @powf(float %x, float 2.0) ret float %r @@ -353,10 +384,8 @@ define <2 x float> @pow2_strictv(<2 x float> %x) { ; CHECK-LABEL: @pow2_strictv( -; ANY-NEXT: [[SQUARE:%.*]] = fmul <2 x float> [[X:%.*]], [[X]] -; ANY-NEXT: ret <2 x float> [[SQUARE]] -; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> ) -; MSVC-NEXT: ret <2 x float> [[POW]] +; CHECK-NEXT: [[SQUARE:%.*]] = fmul <2 x float> [[X:%.*]], [[X]] +; CHECK-NEXT: ret <2 x float> [[SQUARE]] ; %r = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> ) ret <2 x float> %r @@ -364,8 +393,10 @@ define double @pow2_double_strict(double %x) { ; CHECK-LABEL: @pow2_double_strict( -; CHECK-NEXT: [[SQUARE:%.*]] = fmul double [[X:%.*]], [[X]] -; CHECK-NEXT: ret double [[SQUARE]] +; LIB-NEXT: [[SQUARE:%.*]] = fmul double [[X:%.*]], [[X]] +; LIB-NEXT: ret double [[SQUARE]] +; NOLIB-NEXT: [[R:%.*]] = call double @pow(double [[X:%.*]], double 2.000000e+00) +; NOLIB-NEXT: ret double [[R]] ; %r = call double @pow(double %x, double 2.0) ret double %r @@ -373,10 +404,8 @@ define <2 x double> @pow2_double_strictv(<2 x double> %x) { ; CHECK-LABEL: @pow2_double_strictv( -; ANY-NEXT: [[SQUARE:%.*]] = fmul <2 x double> [[X:%.*]], [[X]] -; ANY-NEXT: ret <2 x double> [[SQUARE]] -; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> ) -; MSVC-NEXT: ret <2 x double> [[POW]] +; CHECK-NEXT: [[SQUARE:%.*]] = fmul <2 x double> [[X:%.*]], [[X]] +; CHECK-NEXT: ret <2 x double> [[SQUARE]] ; %r = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> ) ret <2 x double> %r @@ -396,6 +425,8 @@ ; VC64-NEXT: ret float [[SQUARE]] ; VC83-NEXT: [[SQUARE:%.*]] = fmul fast float [[X:%.*]], [[X]] ; VC83-NEXT: ret float [[SQUARE]] +; NOLIB-NEXT: [[R:%.*]] = call fast float @powf(float [[X:%.*]], float 2.000000e+00) +; NOLIB-NEXT: ret float [[R]] ; %r = call fast float @powf(float %x, float 2.0) ret float %r @@ -415,6 +446,8 @@ ; VC64-NEXT: ret float [[RECIPROCAL]] ; VC83-NEXT: [[RECIPROCAL:%.*]] = fdiv float 1.000000e+00, [[X:%.*]] ; VC83-NEXT: ret float [[RECIPROCAL]] +; NOLIB-NEXT: [[R:%.*]] = call float @powf(float [[X:%.*]], float -1.000000e+00) +; NOLIB-NEXT: ret float [[R]] ; %r = call float @powf(float %x, float -1.0) ret float %r @@ -422,10 +455,8 @@ define <2 x float> @pow_neg1_strictv(<2 x float> %x) { ; CHECK-LABEL: @pow_neg1_strictv( -; ANY-NEXT: [[RECIPROCAL:%.*]] = fdiv <2 x float> , [[X:%.*]] -; ANY-NEXT: ret <2 x float> [[RECIPROCAL]] -; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> ) -; MSVC-NEXT: ret <2 x float> [[POW]] +; CHECK-NEXT: [[RECIPROCAL:%.*]] = fdiv <2 x float> , [[X:%.*]] +; CHECK-NEXT: ret <2 x float> [[RECIPROCAL]] ; %r = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> ) ret <2 x float> %r @@ -433,8 +464,10 @@ define double @pow_neg1_double_fast(double %x) { ; CHECK-LABEL: @pow_neg1_double_fast( -; CHECK-NEXT: [[RECIPROCAL:%.*]] = fdiv fast double 1.000000e+00, [[X:%.*]] -; CHECK-NEXT: ret double [[RECIPROCAL]] +; LIB-NEXT: [[RECIPROCAL:%.*]] = fdiv fast double 1.000000e+00, [[X:%.*]] +; LIB-NEXT: ret double [[RECIPROCAL]] +; NOLIB-NEXT: [[R:%.*]] = call fast double @pow(double [[X:%.*]], double -1.000000e+00) +; NOLIB-NEXT: ret double [[R]] ; %r = call fast double @pow(double %x, double -1.0) ret double %r @@ -442,10 +475,8 @@ define <2 x double> @pow_neg1_double_fastv(<2 x double> %x) { ; CHECK-LABEL: @pow_neg1_double_fastv( -; ANY-NEXT: [[RECIPROCAL:%.*]] = fdiv fast <2 x double> , [[X:%.*]] -; ANY-NEXT: ret <2 x double> [[RECIPROCAL]] -; MSVC-NEXT: [[POW:%.*]] = call fast <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> ) -; MSVC-NEXT: ret <2 x double> [[POW]] +; CHECK-NEXT: [[RECIPROCAL:%.*]] = fdiv fast <2 x double> , [[X:%.*]] +; CHECK-NEXT: ret <2 x double> [[RECIPROCAL]] ; %r = call fast <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> ) ret <2 x double> %r diff --git a/llvm/test/Transforms/InstCombine/pow-3.ll b/llvm/test/Transforms/InstCombine/pow-3.ll --- a/llvm/test/Transforms/InstCombine/pow-3.ll +++ b/llvm/test/Transforms/InstCombine/pow-3.ll @@ -15,8 +15,11 @@ define double @sqrt_intrinsic(double %x) { ; CHECK-LABEL: @sqrt_intrinsic( -; CHECK-NEXT: [[RETVAL:%.*]] = call double @llvm.pow.f64(double [[X:%.*]], double 5.000000e-01) -; CHECK-NEXT: ret double [[RETVAL]] +; CHECK-NEXT: [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[X:%.*]]) +; CHECK-NEXT: [[ABS:%.*]] = call double @llvm.fabs.f64(double [[SQRT]]) +; CHECK-NEXT: [[ISINF:%.*]] = fcmp oeq double [[X]], 0xFFF0000000000000 +; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[ISINF]], double 0x7FF0000000000000, double [[ABS]] +; CHECK-NEXT: ret double [[TMP1]] ; %retval = call double @llvm.pow.f64(double %x, double 0.5) ret double %retval