summaryrefslogtreecommitdiffstats
path: root/llvm/test
diff options
context:
space:
mode:
authorPeter Zotov <whitequark@whitequark.org>2016-04-03 12:30:46 +0000
committerPeter Zotov <whitequark@whitequark.org>2016-04-03 12:30:46 +0000
commit0218d0f38355624acbe4960170a97fb67f5af779 (patch)
tree928453f095dee8da0ab01fc75834339169726eaf /llvm/test
parent2075b5d2a122a3790c05ce12941a738da1a8b205 (diff)
downloadbcm5719-llvm-0218d0f38355624acbe4960170a97fb67f5af779.tar.gz
bcm5719-llvm-0218d0f38355624acbe4960170a97fb67f5af779.zip
Mark some FP intrinsics as safe to speculatively execute
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 only error that can happen when executing ceil, floor, nearbyint, rint and round libm functions per POSIX.1-2001 is -ERANGE, and that requires the maximum value of the exponent to be smaller than the number of mantissa bits, which is not the case with any of the floating point types supported by LLVM. The trunc and copysign functions never set errno per per POSIX.1-2001. Differential Revision: http://reviews.llvm.org/D18643 llvm-svn: 265262
Diffstat (limited to 'llvm/test')
-rw-r--r--llvm/test/Transforms/LICM/hoist-round.ll61
1 files changed, 61 insertions, 0 deletions
diff --git a/llvm/test/Transforms/LICM/hoist-round.ll b/llvm/test/Transforms/LICM/hoist-round.ll
new file mode 100644
index 00000000000..361b31e3e54
--- /dev/null
+++ b/llvm/test/Transforms/LICM/hoist-round.ll
@@ -0,0 +1,61 @@
+; RUN: opt -S -licm < %s | FileCheck %s
+
+target datalayout = "E-m:e-p:32:32-i8:8:8-i16:16:16-i64:32:32-f64:32:32-v64:32:32-v128:32:32-a0:0:32-n32"
+
+; This test verifies that ceil, floor, nearbyint, trunc, rint, round,
+; copysign, minnum, maxnum and fabs intrinsics are considered safe
+; to speculate.
+
+; CHECK-LABEL: @test
+; CHECK: call float @llvm.ceil.f32
+; CHECK: call float @llvm.floor.f32
+; CHECK: call float @llvm.nearbyint.f32
+; CHECK: call float @llvm.rint.f32
+; CHECK: call float @llvm.round.f32
+; CHECK: call float @llvm.trunc.f32
+; CHECK: call float @llvm.fabs.f32
+; CHECK: call float @llvm.copysign.f32
+; CHECK: call float @llvm.minnum.f32
+; CHECK: call float @llvm.maxnum.f32
+; CHECK: for.body:
+
+define void @test(float %arg1, float %arg2) {
+entry:
+ br label %for.head
+
+for.head:
+ %IND = phi i32 [ 0, %entry ], [ %IND.new, %for.body ]
+ %CMP = icmp slt i32 %IND, 10
+ br i1 %CMP, label %for.body, label %exit
+
+for.body:
+ %tmp.1 = call float @llvm.ceil.f32(float %arg1)
+ %tmp.2 = call float @llvm.floor.f32(float %tmp.1)
+ %tmp.3 = call float @llvm.nearbyint.f32(float %tmp.2)
+ %tmp.4 = call float @llvm.rint.f32(float %tmp.3)
+ %tmp.5 = call float @llvm.round.f32(float %tmp.4)
+ %tmp.6 = call float @llvm.trunc.f32(float %tmp.5)
+ %tmp.7 = call float @llvm.fabs.f32(float %tmp.6)
+ %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)
+ %IND.new = add i32 %IND, 1
+ br label %for.head
+
+exit:
+ ret void
+}
+
+declare void @consume(float)
+
+declare float @llvm.ceil.f32(float)
+declare float @llvm.floor.f32(float)
+declare float @llvm.nearbyint.f32(float)
+declare float @llvm.rint.f32(float)
+declare float @llvm.round.f32(float)
+declare float @llvm.trunc.f32(float)
+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)
OpenPOWER on IntegriCloud