OSDN Git Service

Mark @llvm.powi.* as safe to speculatively execute.
authorwhitequark <whitequark@whitequark.org>
Wed, 25 Jan 2017 09:32:30 +0000 (09:32 +0000)
committerwhitequark <whitequark@whitequark.org>
Wed, 25 Jan 2017 09:32:30 +0000 (09:32 +0000)
Floating point intrinsics in LLVM are generally not speculatively
executed, since most of them are defined to behave the same as libm
functions, which set errno.

However, the @llvm.powi.* intrinsics do not correspond to any libm
function, and lacks any defined error handling semantics in LangRef.
It most certainly does not alter errno.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293041 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/ValueTracking.cpp
test/Transforms/LICM/hoist-round.ll

index 73455a8..dc8de6d 100644 (file)
@@ -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;
index 9c6a3a1..87a7050 100644 (file)
@@ -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)