diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 73455a87c9fc..dc8de6d58a37 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -3339,6 +3339,10 @@ bool llvm::isSafeToSpeculativelyExecute(const Value *V, case Intrinsic::rint: case Intrinsic::round: return true; + // These intrinsics do not correspond to any libm function, and + // do not set errno. + case Intrinsic::powi: + return true; // TODO: are convert_{from,to}_fp16 safe? // TODO: can we list target-specific intrinsics here? default: break; diff --git a/llvm/test/Transforms/LICM/hoist-round.ll b/llvm/test/Transforms/LICM/hoist-round.ll index 9c6a3a180b50..87a7050668de 100644 --- a/llvm/test/Transforms/LICM/hoist-round.ll +++ b/llvm/test/Transforms/LICM/hoist-round.ll @@ -18,6 +18,7 @@ target datalayout = "E-m:e-p:32:32-i8:8:8-i16:16:16-i64:32:32-f64:32:32-v64:32:3 ; CHECK: call float @llvm.copysign.f32 ; CHECK: call float @llvm.minnum.f32 ; CHECK: call float @llvm.maxnum.f32 +; CHECK: call float @llvm.powi.f32 ; CHECK: for.body: define void @test(float %arg1, float %arg2) { @@ -40,7 +41,8 @@ for.body: %tmp.8 = call float @llvm.copysign.f32(float %tmp.7, float %arg2) %tmp.9 = call float @llvm.minnum.f32(float %tmp.8, float %arg2) %tmp.10 = call float @llvm.maxnum.f32(float %tmp.9, float %arg2) - call void @consume(float %tmp.10) + %tmp.11 = call float @llvm.powi.f32(float %tmp.10, i32 4) + call void @consume(float %tmp.11) %IND.new = add i32 %IND, 1 br label %for.head @@ -60,3 +62,4 @@ declare float @llvm.fabs.f32(float) declare float @llvm.copysign.f32(float, float) declare float @llvm.minnum.f32(float, float) declare float @llvm.maxnum.f32(float, float) +declare float @llvm.powi.f32(float, i32)