summaryrefslogtreecommitdiffstats
path: root/test/Transforms
diff options
context:
space:
mode:
Diffstat (limited to 'test/Transforms')
-rw-r--r--test/Transforms/FunctionAttrs/norecurse.ll2
-rw-r--r--test/Transforms/FunctionImport/Inputs/funcimport.ll15
-rw-r--r--test/Transforms/FunctionImport/Inputs/funcimport_alias.ll7
-rw-r--r--test/Transforms/FunctionImport/funcimport.ll2
-rw-r--r--test/Transforms/FunctionImport/funcimport_alias.ll25
-rw-r--r--test/Transforms/FunctionImport/funcimport_debug.ll14
-rw-r--r--test/Transforms/IPConstantProp/PR16052.ll26
-rw-r--r--test/Transforms/IPConstantProp/PR26044.ll31
-rw-r--r--test/Transforms/Inline/attributes.ll84
-rw-r--r--test/Transforms/InstCombine/fast-math.ll69
-rw-r--r--test/Transforms/InstCombine/inline-intrinsic-assert.ll12
-rw-r--r--test/Transforms/InstCombine/insert-extract-shuffle.ll50
-rw-r--r--test/Transforms/InstCombine/log-pow.ll64
-rw-r--r--test/Transforms/InstCombine/no_cgscc_assert.ll5
-rw-r--r--test/Transforms/InstCombine/pow-exp.ll53
-rw-r--r--test/Transforms/InstCombine/pow-exp2.ll19
-rw-r--r--test/Transforms/InstCombine/pow-sqrt.ll14
-rw-r--r--test/Transforms/InstCombine/printf-3.ll39
-rw-r--r--test/Transforms/InstCombine/tan.ll19
-rw-r--r--test/Transforms/InstSimplify/floating-point-compare.ll41
-rw-r--r--test/Transforms/JumpThreading/pr26096.ll68
-rw-r--r--test/Transforms/JumpThreading/select.ll37
-rw-r--r--test/Transforms/LoopUnroll/partial-unroll-optsize.ll3
-rw-r--r--test/Transforms/LoopUnroll/unloop.ll2
-rw-r--r--test/Transforms/MemCpyOpt/fca2memcpy.ll24
-rw-r--r--test/Transforms/Reassociate/add_across_block_crash.ll20
-rw-r--r--test/Transforms/RewriteStatepointsForGC/constants.ll11
-rw-r--r--test/Transforms/RewriteStatepointsForGC/deopt-bundles/live-vector-nosplit.ll112
-rw-r--r--test/Transforms/RewriteStatepointsForGC/deopt-bundles/live-vector.ll2
-rw-r--r--test/Transforms/RewriteStatepointsForGC/live-vector.ll2
-rw-r--r--test/Transforms/RewriteStatepointsForGC/two-invokes-one-landingpad.ll33
-rw-r--r--test/Transforms/SimplifyCFG/bug-25299.ll40
-rw-r--r--test/Transforms/SimplifyCFG/invoke_unwind.ll42
-rw-r--r--test/Transforms/Util/split-bit-piece.ll45
34 files changed, 905 insertions, 127 deletions
diff --git a/test/Transforms/FunctionAttrs/norecurse.ll b/test/Transforms/FunctionAttrs/norecurse.ll
index 4748119..d5a2d82 100644
--- a/test/Transforms/FunctionAttrs/norecurse.ll
+++ b/test/Transforms/FunctionAttrs/norecurse.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -basicaa -functionattrs -S | FileCheck %s
+; RUN: opt < %s -basicaa -functionattrs -rpo-functionattrs -S | FileCheck %s
; CHECK: define i32 @leaf() #0
define i32 @leaf() {
diff --git a/test/Transforms/FunctionImport/Inputs/funcimport.ll b/test/Transforms/FunctionImport/Inputs/funcimport.ll
index 9655589..79b766b 100644
--- a/test/Transforms/FunctionImport/Inputs/funcimport.ll
+++ b/test/Transforms/FunctionImport/Inputs/funcimport.ll
@@ -10,6 +10,7 @@
define void @globalfunc1() #0 {
entry:
+ call void @funcwithpersonality()
ret void
}
@@ -79,6 +80,20 @@ entry:
ret i32 1
}
+declare i32 @__gxx_personality_v0(...)
+
+; Add enough instructions to prevent import with inst limit of 5
+define internal void @funcwithpersonality() #2 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
+entry:
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ ret void
+}
+
define internal void @staticfunc2() #0 {
entry:
ret void
diff --git a/test/Transforms/FunctionImport/Inputs/funcimport_alias.ll b/test/Transforms/FunctionImport/Inputs/funcimport_alias.ll
new file mode 100644
index 0000000..f897aed
--- /dev/null
+++ b/test/Transforms/FunctionImport/Inputs/funcimport_alias.ll
@@ -0,0 +1,7 @@
+declare void @analias()
+
+define void @callanalias() #0 {
+entry:
+ call void @analias()
+ ret void
+}
diff --git a/test/Transforms/FunctionImport/funcimport.ll b/test/Transforms/FunctionImport/funcimport.ll
index c099b97..52fd53d 100644
--- a/test/Transforms/FunctionImport/funcimport.ll
+++ b/test/Transforms/FunctionImport/funcimport.ll
@@ -73,3 +73,5 @@ declare void @callfuncptr(...) #1
; CHECK-DAG: declare void @weakfunc(...)
declare void @weakfunc(...) #1
+; INSTLIMDEF-DAG: define available_externally hidden void @funcwithpersonality.llvm.2() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
+; INSTLIM5-DAG: declare hidden void @funcwithpersonality.llvm.2()
diff --git a/test/Transforms/FunctionImport/funcimport_alias.ll b/test/Transforms/FunctionImport/funcimport_alias.ll
new file mode 100644
index 0000000..8c7f00f
--- /dev/null
+++ b/test/Transforms/FunctionImport/funcimport_alias.ll
@@ -0,0 +1,25 @@
+; Do setup work for all below tests: generate bitcode and combined index
+; RUN: llvm-as -function-summary %s -o %t.bc
+; RUN: llvm-as -function-summary %p/Inputs/funcimport_alias.ll -o %t2.bc
+; RUN: llvm-lto -thinlto -o %t3 %t.bc %t2.bc
+
+; Do the import now. Ensures that the importer handles an external call
+; from imported callanalias() to a function that is defined already in
+; the dest module, but as an alias.
+; RUN: opt -function-import -summary-file %t3.thinlto.bc %s -S | FileCheck %s
+
+define i32 @main() #0 {
+entry:
+ call void @callanalias()
+ ret i32 0
+}
+
+@analias = alias void (), void ()* @globalfunc
+
+define void @globalfunc() #0 {
+entry:
+ ret void
+}
+
+declare void @callanalias() #1
+; CHECK-DAG: define available_externally void @callanalias()
diff --git a/test/Transforms/FunctionImport/funcimport_debug.ll b/test/Transforms/FunctionImport/funcimport_debug.ll
index c57b5e1..96b73a3 100644
--- a/test/Transforms/FunctionImport/funcimport_debug.ll
+++ b/test/Transforms/FunctionImport/funcimport_debug.ll
@@ -7,8 +7,18 @@
; RUN: opt -function-import -summary-file %t3.thinlto.bc %s -S | FileCheck %s
; CHECK: define available_externally void @func()
-; CHECK: distinct !DISubprogram(name: "main"
-; CHECK: distinct !DISubprogram(name: "func"
+
+; Check that we have exactly two subprograms (that func's subprogram wasn't
+; linked more than once for example), and that they are connected to
+; the subprogram list on a compute unit.
+; CHECK: !{{[0-9]+}} = distinct !DICompileUnit({{.*}} subprograms: ![[SPs1:[0-9]+]]
+; CHECK: ![[SPs1]] = !{![[MAINSP:[0-9]+]]}
+; CHECK: ![[MAINSP]] = distinct !DISubprogram(name: "main"
+; CHECK: !{{[0-9]+}} = distinct !DICompileUnit({{.*}} subprograms: ![[SPs2:[0-9]+]]
+; CHECK-NOT: ![[SPs2]] = !{{{.*}}null{{.*}}}
+; CHECK: ![[SPs2]] = !{![[FUNCSP:[0-9]+]]}
+; CHECK: ![[FUNCSP]] = distinct !DISubprogram(name: "func"
+; CHECK-NOT: distinct !DISubprogram
; ModuleID = 'funcimport_debug.o'
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
diff --git a/test/Transforms/IPConstantProp/PR16052.ll b/test/Transforms/IPConstantProp/PR16052.ll
new file mode 100644
index 0000000..959074d
--- /dev/null
+++ b/test/Transforms/IPConstantProp/PR16052.ll
@@ -0,0 +1,26 @@
+; RUN: opt < %s -S -ipsccp | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i64 @fn2() {
+entry:
+ %conv = sext i32 undef to i64
+ %div = sdiv i64 8, %conv
+ %call2 = call i64 @fn1(i64 %div)
+ ret i64 %call2
+}
+
+; CHECK-DAG: define i64 @fn2(
+; CHECK: %[[CALL:.*]] = call i64 @fn1(i64 undef)
+
+define internal i64 @fn1(i64 %p1) {
+entry:
+ %tobool = icmp ne i64 %p1, 0
+ %cond = select i1 %tobool, i64 %p1, i64 %p1
+ ret i64 %cond
+}
+
+; CHECK-DAG: define internal i64 @fn1(
+; CHECK: %[[SEL:.*]] = select i1 undef, i64 undef, i64 undef
+; CHECK: ret i64 %[[SEL]]
diff --git a/test/Transforms/IPConstantProp/PR26044.ll b/test/Transforms/IPConstantProp/PR26044.ll
new file mode 100644
index 0000000..9e8c61e
--- /dev/null
+++ b/test/Transforms/IPConstantProp/PR26044.ll
@@ -0,0 +1,31 @@
+; RUN: opt < %s -S -ipsccp | FileCheck %s
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @fn2() {
+entry:
+ br label %if.end
+
+for.cond1: ; preds = %if.end, %for.end
+ br i1 undef, label %if.end, label %if.end
+
+if.end: ; preds = %lbl, %for.cond1
+ %e.2 = phi i32* [ undef, %entry ], [ null, %for.cond1 ], [ null, %for.cond1 ]
+ %0 = load i32, i32* %e.2, align 4
+ %call = call i32 @fn1(i32 %0)
+ br label %for.cond1
+}
+
+define internal i32 @fn1(i32 %p1) {
+entry:
+ %tobool = icmp ne i32 %p1, 0
+ %cond = select i1 %tobool, i32 %p1, i32 %p1
+ ret i32 %cond
+}
+
+; CHECK-LABEL: define void @fn2(
+; CHECK: call i32 @fn1(i32 undef)
+
+; CHECK-LABEL: define internal i32 @fn1(
+; CHECK:%[[COND:.*]] = select i1 undef, i32 undef, i32 undef
+; CHECK: ret i32 %[[COND]]
diff --git a/test/Transforms/Inline/attributes.ll b/test/Transforms/Inline/attributes.ll
index a97e6a6..0458fa2 100644
--- a/test/Transforms/Inline/attributes.ll
+++ b/test/Transforms/Inline/attributes.ll
@@ -160,3 +160,87 @@ define i32 @test_target_features1(i32 %i) "target-features"="+sse4.2" {
; CHECK-NEXT: @test_target_features_callee1
; CHECK-NEXT: ret i32
}
+
+define i32 @less-precise-fpmad_callee0(i32 %i) "less-precise-fpmad"="false" {
+ ret i32 %i
+; CHECK: @less-precise-fpmad_callee0(i32 %i) [[FPMAD_FALSE:#[0-9]+]] {
+; CHECK-NEXT: ret i32
+}
+
+define i32 @less-precise-fpmad_callee1(i32 %i) "less-precise-fpmad"="true" {
+ ret i32 %i
+; CHECK: @less-precise-fpmad_callee1(i32 %i) [[FPMAD_TRUE:#[0-9]+]] {
+; CHECK-NEXT: ret i32
+}
+
+define i32 @test_less-precise-fpmad0(i32 %i) "less-precise-fpmad"="false" {
+ %1 = call i32 @less-precise-fpmad_callee0(i32 %i)
+ ret i32 %1
+; CHECK: @test_less-precise-fpmad0(i32 %i) [[FPMAD_FALSE]] {
+; CHECK-NEXT: ret i32
+}
+
+define i32 @test_less-precise-fpmad1(i32 %i) "less-precise-fpmad"="false" {
+ %1 = call i32 @less-precise-fpmad_callee1(i32 %i)
+ ret i32 %1
+; CHECK: @test_less-precise-fpmad1(i32 %i) [[FPMAD_FALSE]] {
+; CHECK-NEXT: ret i32
+}
+
+define i32 @test_less-precise-fpmad2(i32 %i) "less-precise-fpmad"="true" {
+ %1 = call i32 @less-precise-fpmad_callee0(i32 %i)
+ ret i32 %1
+; CHECK: @test_less-precise-fpmad2(i32 %i) [[FPMAD_FALSE]] {
+; CHECK-NEXT: ret i32
+}
+
+define i32 @test_less-precise-fpmad3(i32 %i) "less-precise-fpmad"="true" {
+ %1 = call i32 @less-precise-fpmad_callee1(i32 %i)
+ ret i32 %1
+; CHECK: @test_less-precise-fpmad3(i32 %i) [[FPMAD_TRUE]] {
+; CHECK-NEXT: ret i32
+}
+
+define i32 @no-implicit-float_callee0(i32 %i) {
+ ret i32 %i
+; CHECK: @no-implicit-float_callee0(i32 %i) {
+; CHECK-NEXT: ret i32
+}
+
+define i32 @no-implicit-float_callee1(i32 %i) noimplicitfloat {
+ ret i32 %i
+; CHECK: @no-implicit-float_callee1(i32 %i) [[NOIMPLICITFLOAT:#[0-9]+]] {
+; CHECK-NEXT: ret i32
+}
+
+define i32 @test_no-implicit-float0(i32 %i) {
+ %1 = call i32 @no-implicit-float_callee0(i32 %i)
+ ret i32 %1
+; CHECK: @test_no-implicit-float0(i32 %i) {
+; CHECK-NEXT: ret i32
+}
+
+define i32 @test_no-implicit-float1(i32 %i) {
+ %1 = call i32 @no-implicit-float_callee1(i32 %i)
+ ret i32 %1
+; CHECK: @test_no-implicit-float1(i32 %i) [[NOIMPLICITFLOAT]] {
+; CHECK-NEXT: ret i32
+}
+
+define i32 @test_no-implicit-float2(i32 %i) noimplicitfloat {
+ %1 = call i32 @no-implicit-float_callee0(i32 %i)
+ ret i32 %1
+; CHECK: @test_no-implicit-float2(i32 %i) [[NOIMPLICITFLOAT]] {
+; CHECK-NEXT: ret i32
+}
+
+define i32 @test_no-implicit-float3(i32 %i) noimplicitfloat {
+ %1 = call i32 @no-implicit-float_callee1(i32 %i)
+ ret i32 %1
+; CHECK: @test_no-implicit-float3(i32 %i) [[NOIMPLICITFLOAT]] {
+; CHECK-NEXT: ret i32
+}
+
+; CHECK: attributes [[FPMAD_FALSE]] = { "less-precise-fpmad"="false" }
+; CHECK: attributes [[FPMAD_TRUE]] = { "less-precise-fpmad"="true" }
+; CHECK: attributes [[NOIMPLICITFLOAT]] = { noimplicitfloat }
diff --git a/test/Transforms/InstCombine/fast-math.ll b/test/Transforms/InstCombine/fast-math.ll
index 5bdf48b..6ccf6e9 100644
--- a/test/Transforms/InstCombine/fast-math.ll
+++ b/test/Transforms/InstCombine/fast-math.ll
@@ -555,18 +555,12 @@ define float @fact_div6(float %x) {
; A squared factor fed into a square root intrinsic should be hoisted out
; as a fabs() value.
-; We have to rely on a function-level attribute to enable this optimization
-; because intrinsics don't currently have access to IR-level fast-math
-; flags. If that changes, we can relax the requirement on all of these
-; tests to just specify 'fast' on the sqrt.
-
-attributes #0 = { "unsafe-fp-math" = "true" }
declare double @llvm.sqrt.f64(double)
-define double @sqrt_intrinsic_arg_squared(double %x) #0 {
+define double @sqrt_intrinsic_arg_squared(double %x) {
%mul = fmul fast double %x, %x
- %sqrt = call double @llvm.sqrt.f64(double %mul)
+ %sqrt = call fast double @llvm.sqrt.f64(double %mul)
ret double %sqrt
; CHECK-LABEL: sqrt_intrinsic_arg_squared(
@@ -577,10 +571,10 @@ define double @sqrt_intrinsic_arg_squared(double %x) #0 {
; Check all 6 combinations of a 3-way multiplication tree where
; one factor is repeated.
-define double @sqrt_intrinsic_three_args1(double %x, double %y) #0 {
+define double @sqrt_intrinsic_three_args1(double %x, double %y) {
%mul = fmul fast double %y, %x
%mul2 = fmul fast double %mul, %x
- %sqrt = call double @llvm.sqrt.f64(double %mul2)
+ %sqrt = call fast double @llvm.sqrt.f64(double %mul2)
ret double %sqrt
; CHECK-LABEL: sqrt_intrinsic_three_args1(
@@ -590,10 +584,10 @@ define double @sqrt_intrinsic_three_args1(double %x, double %y) #0 {
; CHECK-NEXT: ret double %1
}
-define double @sqrt_intrinsic_three_args2(double %x, double %y) #0 {
+define double @sqrt_intrinsic_three_args2(double %x, double %y) {
%mul = fmul fast double %x, %y
%mul2 = fmul fast double %mul, %x
- %sqrt = call double @llvm.sqrt.f64(double %mul2)
+ %sqrt = call fast double @llvm.sqrt.f64(double %mul2)
ret double %sqrt
; CHECK-LABEL: sqrt_intrinsic_three_args2(
@@ -603,10 +597,10 @@ define double @sqrt_intrinsic_three_args2(double %x, double %y) #0 {
; CHECK-NEXT: ret double %1
}
-define double @sqrt_intrinsic_three_args3(double %x, double %y) #0 {
+define double @sqrt_intrinsic_three_args3(double %x, double %y) {
%mul = fmul fast double %x, %x
%mul2 = fmul fast double %mul, %y
- %sqrt = call double @llvm.sqrt.f64(double %mul2)
+ %sqrt = call fast double @llvm.sqrt.f64(double %mul2)
ret double %sqrt
; CHECK-LABEL: sqrt_intrinsic_three_args3(
@@ -616,10 +610,10 @@ define double @sqrt_intrinsic_three_args3(double %x, double %y) #0 {
; CHECK-NEXT: ret double %1
}
-define double @sqrt_intrinsic_three_args4(double %x, double %y) #0 {
+define double @sqrt_intrinsic_three_args4(double %x, double %y) {
%mul = fmul fast double %y, %x
%mul2 = fmul fast double %x, %mul
- %sqrt = call double @llvm.sqrt.f64(double %mul2)
+ %sqrt = call fast double @llvm.sqrt.f64(double %mul2)
ret double %sqrt
; CHECK-LABEL: sqrt_intrinsic_three_args4(
@@ -629,10 +623,10 @@ define double @sqrt_intrinsic_three_args4(double %x, double %y) #0 {
; CHECK-NEXT: ret double %1
}
-define double @sqrt_intrinsic_three_args5(double %x, double %y) #0 {
+define double @sqrt_intrinsic_three_args5(double %x, double %y) {
%mul = fmul fast double %x, %y
%mul2 = fmul fast double %x, %mul
- %sqrt = call double @llvm.sqrt.f64(double %mul2)
+ %sqrt = call fast double @llvm.sqrt.f64(double %mul2)
ret double %sqrt
; CHECK-LABEL: sqrt_intrinsic_three_args5(
@@ -642,10 +636,10 @@ define double @sqrt_intrinsic_three_args5(double %x, double %y) #0 {
; CHECK-NEXT: ret double %1
}
-define double @sqrt_intrinsic_three_args6(double %x, double %y) #0 {
+define double @sqrt_intrinsic_three_args6(double %x, double %y) {
%mul = fmul fast double %x, %x
%mul2 = fmul fast double %y, %mul
- %sqrt = call double @llvm.sqrt.f64(double %mul2)
+ %sqrt = call fast double @llvm.sqrt.f64(double %mul2)
ret double %sqrt
; CHECK-LABEL: sqrt_intrinsic_three_args6(
@@ -655,10 +649,25 @@ define double @sqrt_intrinsic_three_args6(double %x, double %y) #0 {
; CHECK-NEXT: ret double %1
}
-define double @sqrt_intrinsic_arg_4th(double %x) #0 {
+; If any operation is not 'fast', we can't simplify.
+
+define double @sqrt_intrinsic_not_so_fast(double %x, double %y) {
+ %mul = fmul double %x, %x
+ %mul2 = fmul fast double %mul, %y
+ %sqrt = call fast double @llvm.sqrt.f64(double %mul2)
+ ret double %sqrt
+
+; CHECK-LABEL: sqrt_intrinsic_not_so_fast(
+; CHECK-NEXT: %mul = fmul double %x, %x
+; CHECK-NEXT: %mul2 = fmul fast double %mul, %y
+; CHECK-NEXT: %sqrt = call fast double @llvm.sqrt.f64(double %mul2)
+; CHECK-NEXT: ret double %sqrt
+}
+
+define double @sqrt_intrinsic_arg_4th(double %x) {
%mul = fmul fast double %x, %x
%mul2 = fmul fast double %mul, %mul
- %sqrt = call double @llvm.sqrt.f64(double %mul2)
+ %sqrt = call fast double @llvm.sqrt.f64(double %mul2)
ret double %sqrt
; CHECK-LABEL: sqrt_intrinsic_arg_4th(
@@ -666,11 +675,11 @@ define double @sqrt_intrinsic_arg_4th(double %x) #0 {
; CHECK-NEXT: ret double %mul
}
-define double @sqrt_intrinsic_arg_5th(double %x) #0 {
+define double @sqrt_intrinsic_arg_5th(double %x) {
%mul = fmul fast double %x, %x
%mul2 = fmul fast double %mul, %x
%mul3 = fmul fast double %mul2, %mul
- %sqrt = call double @llvm.sqrt.f64(double %mul3)
+ %sqrt = call fast double @llvm.sqrt.f64(double %mul3)
ret double %sqrt
; CHECK-LABEL: sqrt_intrinsic_arg_5th(
@@ -686,9 +695,9 @@ declare float @sqrtf(float)
declare double @sqrt(double)
declare fp128 @sqrtl(fp128)
-define float @sqrt_call_squared_f32(float %x) #0 {
+define float @sqrt_call_squared_f32(float %x) {
%mul = fmul fast float %x, %x
- %sqrt = call float @sqrtf(float %mul)
+ %sqrt = call fast float @sqrtf(float %mul)
ret float %sqrt
; CHECK-LABEL: sqrt_call_squared_f32(
@@ -696,9 +705,9 @@ define float @sqrt_call_squared_f32(float %x) #0 {
; CHECK-NEXT: ret float %fabs
}
-define double @sqrt_call_squared_f64(double %x) #0 {
+define double @sqrt_call_squared_f64(double %x) {
%mul = fmul fast double %x, %x
- %sqrt = call double @sqrt(double %mul)
+ %sqrt = call fast double @sqrt(double %mul)
ret double %sqrt
; CHECK-LABEL: sqrt_call_squared_f64(
@@ -706,9 +715,9 @@ define double @sqrt_call_squared_f64(double %x) #0 {
; CHECK-NEXT: ret double %fabs
}
-define fp128 @sqrt_call_squared_f128(fp128 %x) #0 {
+define fp128 @sqrt_call_squared_f128(fp128 %x) {
%mul = fmul fast fp128 %x, %x
- %sqrt = call fp128 @sqrtl(fp128 %mul)
+ %sqrt = call fast fp128 @sqrtl(fp128 %mul)
ret fp128 %sqrt
; CHECK-LABEL: sqrt_call_squared_f128(
diff --git a/test/Transforms/InstCombine/inline-intrinsic-assert.ll b/test/Transforms/InstCombine/inline-intrinsic-assert.ll
index c6446d4..8eecb3f 100644
--- a/test/Transforms/InstCombine/inline-intrinsic-assert.ll
+++ b/test/Transforms/InstCombine/inline-intrinsic-assert.ll
@@ -4,7 +4,7 @@
; The inliner should not add an edge to an intrinsic and
; then assert that it did not add an edge to an intrinsic!
-define float @foo(float %f1) #0 {
+define float @foo(float %f1) {
%call = call float @bar(float %f1)
ret float %call
@@ -13,18 +13,16 @@ define float @foo(float %f1) #0 {
; CHECK-NEXT: ret float
}
-define float @bar(float %f1) #0 {
+define float @bar(float %f1) {
%call = call float @sqr(float %f1)
- %call1 = call float @sqrtf(float %call) #0
+ %call1 = call fast float @sqrtf(float %call)
ret float %call1
}
-define float @sqr(float %f) #0 {
+define float @sqr(float %f) {
%mul = fmul fast float %f, %f
ret float %mul
}
-declare float @sqrtf(float) #0
-
-attributes #0 = { "unsafe-fp-math"="true" }
+declare float @sqrtf(float)
diff --git a/test/Transforms/InstCombine/insert-extract-shuffle.ll b/test/Transforms/InstCombine/insert-extract-shuffle.ll
index 4223660..47c2a13 100644
--- a/test/Transforms/InstCombine/insert-extract-shuffle.ll
+++ b/test/Transforms/InstCombine/insert-extract-shuffle.ll
@@ -125,3 +125,53 @@ end:
ret <8 x i16> %t6
}
+; The widening shuffle must be inserted at a valid point (after the PHIs).
+
+define <4 x double> @pr25999_phis1(i1 %c, <2 x double> %a, <4 x double> %b) {
+; CHECK-LABEL: @pr25999_phis1(
+; CHECK: %tmp1 = phi <2 x double> [ %a, %bb1 ], [ %r, %bb2 ]
+; CHECK-NEXT: %tmp2 = phi <4 x double> [ %b, %bb1 ], [ zeroinitializer, %bb2 ]
+; CHECK-NEXT: %[[WIDEVEC:.*]] = shufflevector <2 x double> %tmp1, <2 x double> undef, <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef>
+; CHECK-NEXT: %tmp4 = shufflevector <4 x double> %tmp2, <4 x double> %[[WIDEVEC]], <4 x i32> <i32 0, i32 1, i32 4, i32 3>
+; CHECK-NEXT: ret <4 x double> %tmp4
+bb1:
+ br i1 %c, label %bb2, label %bb3
+
+bb2:
+ %r = call <2 x double> @dummy(<2 x double> %a)
+ br label %bb3
+
+bb3:
+ %tmp1 = phi <2 x double> [ %a, %bb1 ], [ %r, %bb2 ]
+ %tmp2 = phi <4 x double> [ %b, %bb1 ], [ zeroinitializer, %bb2 ]
+ %tmp3 = extractelement <2 x double> %tmp1, i32 0
+ %tmp4 = insertelement <4 x double> %tmp2, double %tmp3, i32 2
+ ret <4 x double> %tmp4
+}
+
+declare <2 x double> @dummy(<2 x double>)
+
+define <4 x double> @pr25999_phis2(i1 %c, <2 x double> %a, <4 x double> %b) {
+; CHECK-LABEL: @pr25999_phis2(
+; CHECK: %tmp1 = phi <2 x double> [ %a, %bb1 ], [ %r, %bb2 ]
+; CHECK-NEXT: %tmp2 = phi <4 x double> [ %b, %bb1 ], [ zeroinitializer, %bb2 ]
+; CHECK-NEXT: %d = fadd <2 x double> %tmp1, %tmp1
+; CHECK-NEXT: %[[WIDEVEC:.*]] = shufflevector <2 x double> %d, <2 x double> undef, <4 x i32> <i32 0, i32 undef, i32 undef, i32 undef>
+; CHECK-NEXT: %tmp4 = shufflevector <4 x double> %tmp2, <4 x double> %[[WIDEVEC]], <4 x i32> <i32 0, i32 1, i32 4, i32 3>
+; CHECK-NEXT: ret <4 x double> %tmp4
+bb1:
+ br i1 %c, label %bb2, label %bb3
+
+bb2:
+ %r = call <2 x double> @dummy(<2 x double> %a)
+ br label %bb3
+
+bb3:
+ %tmp1 = phi <2 x double> [ %a, %bb1 ], [ %r, %bb2 ]
+ %tmp2 = phi <4 x double> [ %b, %bb1 ], [ zeroinitializer, %bb2 ]
+ %d = fadd <2 x double> %tmp1, %tmp1
+ %tmp3 = extractelement <2 x double> %d, i32 0
+ %tmp4 = insertelement <4 x double> %tmp2, double %tmp3, i32 2
+ ret <4 x double> %tmp4
+}
+
diff --git a/test/Transforms/InstCombine/log-pow.ll b/test/Transforms/InstCombine/log-pow.ll
index c5ca168..a0c10d0 100644
--- a/test/Transforms/InstCombine/log-pow.ll
+++ b/test/Transforms/InstCombine/log-pow.ll
@@ -1,41 +1,61 @@
; RUN: opt < %s -instcombine -S | FileCheck %s
-define double @mylog(double %x, double %y) #0 {
-entry:
+define double @log_pow(double %x, double %y) {
+ %pow = call fast double @llvm.pow.f64(double %x, double %y)
+ %call = call fast double @log(double %pow)
+ ret double %call
+}
+
+; CHECK-LABEL: define double @log_pow(
+; CHECK-NEXT: %log = call fast double @log(double %x)
+; CHECK-NEXT: %mul = fmul fast double %log, %y
+; CHECK-NEXT: ret double %mul
+
+define double @log_pow_not_fast(double %x, double %y) {
%pow = call double @llvm.pow.f64(double %x, double %y)
- %call = call double @log(double %pow) #0
+ %call = call fast double @log(double %pow)
ret double %call
}
-; CHECK-LABEL: define double @mylog(
-; CHECK: %log = call fast double @log(double %x) #0
-; CHECK: %mul = fmul fast double %log, %y
-; CHECK: ret double %mul
-; CHECK: }
+; CHECK-LABEL: define double @log_pow_not_fast(
+; CHECK-NEXT: %pow = call double @llvm.pow.f64(double %x, double %y)
+; CHECK-NEXT: %call = call fast double @log(double %pow)
+; CHECK-NEXT: ret double %call
-define double @test2(double ()* %fptr, double %p1) #0 {
+define double @function_pointer(double ()* %fptr, double %p1) {
%call1 = call double %fptr()
%pow = call double @log(double %call1)
ret double %pow
}
-; CHECK-LABEL: @test2
-; CHECK: log
+; CHECK-LABEL: @function_pointer
+; CHECK-NEXT: %call1 = call double %fptr()
+; CHECK-NEXT: %pow = call double @log(double %call1)
+; CHECK-NEXT: ret double %pow
+
+define double @log_exp2(double %x) {
+ %call2 = call fast double @exp2(double %x)
+ %call3 = call fast double @log(double %call2)
+ ret double %call3
+}
+
+; CHECK-LABEL: @log_exp2
+; CHECK-NEXT: %call2 = call fast double @exp2(double %x)
+; CHECK-NEXT: %logmul = fmul fast double %x, 0x3FE62E42FEFA39EF
+; CHECK-NEXT: ret double %logmul
-define double @test3(double %x) #0 {
- %call2 = call double @exp2(double %x) #0
- %call3 = call double @log(double %call2) #0
+define double @log_exp2_not_fast(double %x) {
+ %call2 = call double @exp2(double %x)
+ %call3 = call fast double @log(double %call2)
ret double %call3
}
-; CHECK-LABEL: @test3
-; CHECK: %call2 = call double @exp2(double %x) #0
-; CHECK: %logmul = fmul fast double %x, 0x3FE62E42FEFA39EF
-; CHECK: ret double %logmul
-; CHECK: }
+; CHECK-LABEL: @log_exp2_not_fast
+; CHECK-NEXT: %call2 = call double @exp2(double %x)
+; CHECK-NEXT: %call3 = call fast double @log(double %call2)
+; CHECK-NEXT: ret double %call3
-declare double @log(double) #0
-declare double @exp2(double) #0
+declare double @log(double)
+declare double @exp2(double)
declare double @llvm.pow.f64(double, double)
-attributes #0 = { "unsafe-fp-math"="true" }
diff --git a/test/Transforms/InstCombine/no_cgscc_assert.ll b/test/Transforms/InstCombine/no_cgscc_assert.ll
index 3df04d2..677066f 100644
--- a/test/Transforms/InstCombine/no_cgscc_assert.ll
+++ b/test/Transforms/InstCombine/no_cgscc_assert.ll
@@ -6,7 +6,7 @@
define float @bar(float %f) #0 {
%mul = fmul fast float %f, %f
- %call1 = call float @sqrtf(float %mul) #0
+ %call1 = call fast float @sqrtf(float %mul)
ret float %call1
; CHECK-LABEL: @bar(
@@ -14,6 +14,5 @@ define float @bar(float %f) #0 {
; CHECK-NEXT: ret float
}
-declare float @sqrtf(float) #0
+declare float @sqrtf(float)
-attributes #0 = { readnone "unsafe-fp-math"="true" }
diff --git a/test/Transforms/InstCombine/pow-exp.ll b/test/Transforms/InstCombine/pow-exp.ll
index acc5127..594594a 100644
--- a/test/Transforms/InstCombine/pow-exp.ll
+++ b/test/Transforms/InstCombine/pow-exp.ll
@@ -1,28 +1,49 @@
; RUN: opt < %s -instcombine -S | FileCheck %s
-define double @mypow(double %x, double %y) #0 {
-entry:
+define double @pow_exp(double %x, double %y) {
+ %call = call fast double @exp(double %x) nounwind readnone
+ %pow = call fast double @llvm.pow.f64(double %call, double %y)
+ ret double %pow
+}
+
+; CHECK-LABEL: define double @pow_exp(
+; CHECK-NEXT: %mul = fmul fast double %x, %y
+; CHECK-NEXT: %exp = call fast double @exp(double %mul)
+; CHECK-NEXT: ret double %exp
+
+define double @pow_exp2(double %x, double %y) {
+ %call = call fast double @exp2(double %x) nounwind readnone
+ %pow = call fast double @llvm.pow.f64(double %call, double %y)
+ ret double %pow
+}
+
+; CHECK-LABEL: define double @pow_exp2(
+; CHECK-NEXT: %mul = fmul fast double %x, %y
+; CHECK-NEXT: %exp2 = call fast double @exp2(double %mul)
+; CHECK-NEXT: ret double %exp2
+
+define double @pow_exp_not_fast(double %x, double %y) {
%call = call double @exp(double %x)
- %pow = call double @llvm.pow.f64(double %call, double %y)
+ %pow = call fast double @llvm.pow.f64(double %call, double %y)
ret double %pow
}
-; CHECK-LABEL: define double @mypow(
-; CHECK: %mul = fmul fast double %x, %y
-; CHECK: %exp = call fast double @exp(double %mul) #0
-; CHECK: ret double %exp
-; CHECK: }
+; CHECK-LABEL: define double @pow_exp_not_fast(
+; CHECK-NEXT: %call = call double @exp(double %x)
+; CHECK-NEXT: %pow = call fast double @llvm.pow.f64(double %call, double %y)
+; CHECK-NEXT: ret double %pow
-define double @test2(double ()* %fptr, double %p1) #0 {
- %call1 = call double %fptr()
- %pow = call double @llvm.pow.f64(double %call1, double %p1)
+define double @function_pointer(double ()* %fptr, double %p1) {
+ %call1 = call fast double %fptr()
+ %pow = call fast double @llvm.pow.f64(double %call1, double %p1)
ret double %pow
}
-; CHECK-LABEL: @test2
-; CHECK: llvm.pow.f64
+; CHECK-LABEL: @function_pointer
+; CHECK-NEXT: %call1 = call fast double %fptr()
+; CHECK-NEXT: %pow = call fast double @llvm.pow.f64(double %call1, double %p1)
-declare double @exp(double) #1
+declare double @exp(double)
+declare double @exp2(double)
declare double @llvm.pow.f64(double, double)
-attributes #0 = { "unsafe-fp-math"="true" }
-attributes #1 = { "unsafe-fp-math"="true" }
+
diff --git a/test/Transforms/InstCombine/pow-exp2.ll b/test/Transforms/InstCombine/pow-exp2.ll
deleted file mode 100644
index c42cab3..0000000
--- a/test/Transforms/InstCombine/pow-exp2.ll
+++ /dev/null
@@ -1,19 +0,0 @@
-; RUN: opt < %s -instcombine -S | FileCheck %s
-
-define double @mypow(double %x, double %y) #0 {
-entry:
- %call = call double @exp2(double %x)
- %pow = call double @llvm.pow.f64(double %call, double %y)
- ret double %pow
-}
-
-; CHECK-LABEL: define double @mypow(
-; CHECK: %mul = fmul fast double %x, %y
-; CHECK: %exp2 = call fast double @exp2(double %mul) #0
-; CHECK: ret double %exp2
-; CHECK: }
-
-declare double @exp2(double) #1
-declare double @llvm.pow.f64(double, double)
-attributes #0 = { "unsafe-fp-math"="true" }
-attributes #1 = { "unsafe-fp-math"="true" }
diff --git a/test/Transforms/InstCombine/pow-sqrt.ll b/test/Transforms/InstCombine/pow-sqrt.ll
index 8fc74e4..1e6166c 100644
--- a/test/Transforms/InstCombine/pow-sqrt.ll
+++ b/test/Transforms/InstCombine/pow-sqrt.ll
@@ -1,15 +1,13 @@
; RUN: opt < %s -instcombine -S | FileCheck %s
-define double @mypow(double %x) #0 {
-entry:
- %pow = call double @llvm.pow.f64(double %x, double 5.000000e-01)
+define double @pow_half(double %x) {
+ %pow = call fast double @llvm.pow.f64(double %x, double 5.000000e-01)
ret double %pow
}
-; CHECK-LABEL: define double @mypow(
-; CHECK: %sqrt = call double @sqrt(double %x) #1
-; CHECK: ret double %sqrt
-; CHECK: }
+; CHECK-LABEL: define double @pow_half(
+; CHECK-NEXT: %sqrt = call fast double @sqrt(double %x)
+; CHECK-NEXT: ret double %sqrt
declare double @llvm.pow.f64(double, double)
-attributes #0 = { "unsafe-fp-math"="true" }
+
diff --git a/test/Transforms/InstCombine/printf-3.ll b/test/Transforms/InstCombine/printf-3.ll
new file mode 100644
index 0000000..8f3a36a
--- /dev/null
+++ b/test/Transforms/InstCombine/printf-3.ll
@@ -0,0 +1,39 @@
+; Test that the printf library call simplifier works correctly.
+;
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc18.0.0"
+
+@.str = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
+
+define void @test1() personality i32 (...)* @__CxxFrameHandler3 {
+entry:
+ invoke void @_CxxThrowException(i8* null, i8* null)
+ to label %unreachable unwind label %catch.dispatch
+
+catch.dispatch:
+ %cs = catchswitch within none [label %catch] unwind to caller
+
+catch:
+ %cp = catchpad within %cs [i8* null, i32 64, i8* null]
+ %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i32 0, i32 0)) [ "funclet"(token %cp) ]
+ catchret from %cp to label %try.cont
+
+try.cont:
+ ret void
+
+unreachable:
+ unreachable
+}
+
+; CHECK-DAG: define void @test1(
+; CHECK: %[[CS:.*]] = catchswitch within none
+; CHECK: %[[CP:.*]] = catchpad within %[[CS]] [i8* null, i32 64, i8* null]
+; CHECK: call i32 @putchar(i32 10) [ "funclet"(token %[[CP]]) ]
+
+declare void @_CxxThrowException(i8*, i8*)
+
+declare i32 @__CxxFrameHandler3(...)
+
+declare i32 @printf(i8*, ...)
diff --git a/test/Transforms/InstCombine/tan.ll b/test/Transforms/InstCombine/tan.ll
index 15a832f..6ea1168 100644
--- a/test/Transforms/InstCombine/tan.ll
+++ b/test/Transforms/InstCombine/tan.ll
@@ -1,24 +1,23 @@
; RUN: opt < %s -instcombine -S | FileCheck %s
-define float @mytan(float %x) #0 {
-entry:
- %call = call float @atanf(float %x)
- %call1 = call float @tanf(float %call)
+define float @mytan(float %x) {
+ %call = call fast float @atanf(float %x)
+ %call1 = call fast float @tanf(float %call)
ret float %call1
}
; CHECK-LABEL: define float @mytan(
; CHECK: ret float %x
-define float @test2(float ()* %fptr) #0 {
- %call1 = call float %fptr()
- %tan = call float @tanf(float %call1)
+define float @test2(float ()* %fptr) {
+ %call1 = call fast float %fptr()
+ %tan = call fast float @tanf(float %call1)
ret float %tan
}
; CHECK-LABEL: @test2
; CHECK: tanf
-declare float @tanf(float) #0
-declare float @atanf(float) #0
-attributes #0 = { "unsafe-fp-math"="true" }
+declare float @tanf(float)
+declare float @atanf(float)
+
diff --git a/test/Transforms/InstSimplify/floating-point-compare.ll b/test/Transforms/InstSimplify/floating-point-compare.ll
index 8174f58..b148d99 100644
--- a/test/Transforms/InstSimplify/floating-point-compare.ll
+++ b/test/Transforms/InstSimplify/floating-point-compare.ll
@@ -8,6 +8,8 @@ declare float @llvm.fabs.f32(float)
declare float @llvm.sqrt.f32(float)
declare double @llvm.powi.f64(double,i32)
declare float @llvm.exp.f32(float)
+declare float @llvm.minnum.f32(float, float)
+declare float @llvm.maxnum.f32(float, float)
declare double @llvm.exp2.f64(double)
declare float @llvm.fma.f32(float,float,float)
@@ -58,6 +60,45 @@ define i1 @orderedLessZeroPowi(double,double) {
ret i1 %olt
}
+; CHECK-LABEL: @orderedLessZeroUIToFP(
+define i1 @orderedLessZeroUIToFP(i32) {
+ %a = uitofp i32 %0 to float
+ %uge = fcmp uge float %a, 0.000000e+00
+; CHECK: ret i1 true
+ ret i1 %uge
+}
+
+; CHECK-LABEL: @orderedLessZeroSelect(
+define i1 @orderedLessZeroSelect(float, float) {
+ %a = call float @llvm.exp.f32(float %0)
+ %b = call float @llvm.fabs.f32(float %1)
+ %c = fcmp olt float %0, %1
+ %d = select i1 %c, float %a, float %b
+ %e = fadd float %d, 1.0
+ %uge = fcmp uge float %e, 0.000000e+00
+; CHECK: ret i1 true
+ ret i1 %uge
+}
+
+; CHECK-LABEL: @orderedLessZeroMinNum(
+define i1 @orderedLessZeroMinNum(float, float) {
+ %a = call float @llvm.exp.f32(float %0)
+ %b = call float @llvm.fabs.f32(float %1)
+ %c = call float @llvm.minnum.f32(float %a, float %b)
+ %uge = fcmp uge float %c, 0.000000e+00
+; CHECK: ret i1 true
+ ret i1 %uge
+}
+
+; CHECK-LABEL: @orderedLessZeroMaxNum(
+define i1 @orderedLessZeroMaxNum(float, float) {
+ %a = call float @llvm.exp.f32(float %0)
+ %b = call float @llvm.maxnum.f32(float %a, float %1)
+ %uge = fcmp uge float %b, 0.000000e+00
+; CHECK: ret i1 true
+ ret i1 %uge
+}
+
define i1 @nonans1(double %in1, double %in2) {
%cmp = fcmp nnan uno double %in1, %in2
ret i1 %cmp
diff --git a/test/Transforms/JumpThreading/pr26096.ll b/test/Transforms/JumpThreading/pr26096.ll
new file mode 100644
index 0000000..2671e82
--- /dev/null
+++ b/test/Transforms/JumpThreading/pr26096.ll
@@ -0,0 +1,68 @@
+; RUN: opt -prune-eh -inline -jump-threading -S < %s | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@d = external global i32*, align 8
+
+define void @fn3(i1 %B) {
+entry:
+ br i1 %B, label %if.end, label %if.then
+
+if.then: ; preds = %entry
+ call void @fn2()
+ ret void
+
+if.end: ; preds = %entry
+ call void @fn2()
+ ret void
+}
+
+define internal void @fn2() unnamed_addr {
+entry:
+ call void @fn1()
+ call void @fn1()
+ call void @fn1()
+ unreachable
+}
+
+; CHECK-LABEL: define internal void @fn2(
+; CHECK: %[[LOAD:.*]] = load i32*, i32** @d, align 8
+; CHECK: %tobool1.i = icmp eq i32* %[[LOAD]], null
+
+define internal void @fn1() unnamed_addr {
+entry:
+ br label %for.body
+
+for.body: ; preds = %entry
+ %0 = load i32*, i32** @d, align 8
+ %tobool1 = icmp eq i32* %0, null
+ br i1 %tobool1, label %cond.false, label %cond.end
+
+cond.false: ; preds = %for.body
+ call void @__assert_fail(i8* null)
+ unreachable
+
+cond.end: ; preds = %for.body
+ %1 = load i32*, i32** @d, align 8
+ %cmp = icmp eq i32* %1, null
+ br i1 %cmp, label %cond.end4, label %cond.false3
+
+cond.false3: ; preds = %cond.end
+ call void @__assert_fail(i8* null)
+ unreachable
+
+cond.end4: ; preds = %cond.end
+ call void @__assert_fail(i8* null)
+ unreachable
+
+for.end: ; No predecessors!
+ ret void
+}
+
+declare void @__assert_fail(i8*)
+
+; Function Attrs: noreturn nounwind
+declare void @llvm.trap() #0
+
+attributes #0 = { noreturn nounwind }
diff --git a/test/Transforms/JumpThreading/select.ll b/test/Transforms/JumpThreading/select.ll
index 595cacb..6a3cf7e 100644
--- a/test/Transforms/JumpThreading/select.ll
+++ b/test/Transforms/JumpThreading/select.ll
@@ -250,3 +250,40 @@ if.end: ; preds = %if.then, %cond.end4
; CHECK: br i1 %cmp6, label %if.then, label %if.end
; CHECK: br label %if.end
}
+
+
+define i32 @unfold3(i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z, i32 %j) nounwind {
+entry:
+ %add3 = add nsw i32 %j, 2
+ %cmp.i = icmp slt i32 %u, %v
+ br i1 %cmp.i, label %.exit, label %cond.false.i
+
+cond.false.i: ; preds = %entry
+ %cmp4.i = icmp sgt i32 %u, %v
+ br i1 %cmp4.i, label %.exit, label %cond.false.6.i
+
+cond.false.6.i: ; preds = %cond.false.i
+ %cmp8.i = icmp slt i32 %w, %x
+ br i1 %cmp8.i, label %.exit, label %cond.false.10.i
+
+cond.false.10.i: ; preds = %cond.false.6.i
+ %cmp13.i = icmp sgt i32 %w, %x
+ br i1 %cmp13.i, label %.exit, label %cond.false.15.i
+
+cond.false.15.i: ; preds = %cond.false.10.i
+ %phitmp = icmp sge i32 %y, %z
+ br label %.exit
+
+.exit: ; preds = %entry, %cond.false.i, %cond.false.6.i, %cond.false.10.i, %cond.false.15.i
+ %cond23.i = phi i1 [ false, %entry ], [ true, %cond.false.i ], [ false, %cond.false.6.i ], [ %phitmp, %cond.false.15.i ], [ true, %cond.false.10.i ]
+ %j.add3 = select i1 %cond23.i, i32 %j, i32 %add3
+ ret i32 %j.add3
+
+; CHECK-LABEL: @unfold3
+; CHECK: br i1 %cmp.i, label %.exit.thread2, label %cond.false.i
+; CHECK: br i1 %cmp4.i, label %.exit.thread, label %cond.false.6.i
+; CHECK: br i1 %cmp8.i, label %.exit.thread2, label %cond.false.10.i
+; CHECK: br i1 %cmp13.i, label %.exit.thread, label %.exit
+; CHECK: br i1 %phitmp, label %.exit.thread, label %.exit.thread2
+; CHECK: br label %.exit.thread2
+}
diff --git a/test/Transforms/LoopUnroll/partial-unroll-optsize.ll b/test/Transforms/LoopUnroll/partial-unroll-optsize.ll
index a650317..e5e0151 100644
--- a/test/Transforms/LoopUnroll/partial-unroll-optsize.ll
+++ b/test/Transforms/LoopUnroll/partial-unroll-optsize.ll
@@ -1,4 +1,6 @@
; RUN: opt < %s -S -loop-unroll -unroll-allow-partial | FileCheck %s
+; RUN: sed -e 's/optsize/minsize/' %s | opt -S -loop-unroll -unroll-allow-partial | FileCheck %s
+
; Loop size = 3, when the function has the optsize attribute, the
; OptSizeUnrollThreshold, i.e. 50, is used, hence the loop should be unrolled
; by 32 times because (1 * 32) + 2 < 50 (whereas (1 * 64 + 2) is not).
@@ -49,4 +51,3 @@ exit:
; CHECK-NEXT: add
; CHECK-NEXT: add
; CHECK-NEXT: icmp
-
diff --git a/test/Transforms/LoopUnroll/unloop.ll b/test/Transforms/LoopUnroll/unloop.ll
index b98b4a3..720b2ae 100644
--- a/test/Transforms/LoopUnroll/unloop.ll
+++ b/test/Transforms/LoopUnroll/unloop.ll
@@ -1,6 +1,6 @@
; RUN: opt < %s -S -loop-unroll -verify-loop-info | FileCheck %s
;
-; Unit tests for LoopInfo::updateUnloop.
+; Unit tests for LoopInfo::markAsRemoved.
declare i1 @check() nounwind
diff --git a/test/Transforms/MemCpyOpt/fca2memcpy.ll b/test/Transforms/MemCpyOpt/fca2memcpy.ll
index 75a1a8f..c8a1268 100644
--- a/test/Transforms/MemCpyOpt/fca2memcpy.ll
+++ b/test/Transforms/MemCpyOpt/fca2memcpy.ll
@@ -3,7 +3,7 @@
target datalayout = "e-i64:64-f80:128-n8:16:32:64"
target triple = "x86_64-unknown-linux-gnu"
-%S = type { i8*, i32 }
+%S = type { i8*, i8, i32 }
define void @copy(%S* %src, %S* %dst) {
; CHECK-LABEL: copy
@@ -37,8 +37,10 @@ define void @noaliasdst(%S* %src, %S* noalias %dst) {
define void @destroysrc(%S* %src, %S* %dst) {
; CHECK-LABEL: destroysrc
-; CHECK-NOT: call
-; CHECK: ret void
+; CHECK: load %S, %S* %src
+; CHECK: call void @llvm.memset.p0i8.i64
+; CHECK-NEXT: store %S %1, %S* %dst
+; CHECK-NEXT: ret void
%1 = load %S, %S* %src
store %S zeroinitializer, %S* %src
store %S %1, %S* %dst
@@ -49,7 +51,7 @@ define void @destroynoaliassrc(%S* noalias %src, %S* %dst) {
; CHECK-LABEL: destroynoaliassrc
; CHECK-NOT: load
; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
-; CHECK-NEXT: store %S zeroinitializer, %S* %src
+; CHECK-NEXT: call void @llvm.memset.p0i8.i64
; CHECK-NEXT: ret void
%1 = load %S, %S* %src
store %S zeroinitializer, %S* %src
@@ -70,3 +72,17 @@ define void @copyalias(%S* %src, %S* %dst) {
store %S %2, %S* %dst
ret void
}
+
+
+; The GEP is present after the aliasing store, preventing to move the memcpy before
+; (without further analysis/transformation)
+define void @copyaliaswithproducerinbetween(%S* %src, %S* %dst) {
+; CHECK-LABEL: copyalias
+; CHECK-NEXT: [[LOAD:%[a-z0-9\.]+]] = load %S, %S* %src
+; CHECK-NOT: call
+ %1 = load %S, %S* %src
+ store %S undef, %S* %dst
+ %dst2 = getelementptr %S , %S* %dst, i64 1
+ store %S %1, %S* %dst2
+ ret void
+}
diff --git a/test/Transforms/Reassociate/add_across_block_crash.ll b/test/Transforms/Reassociate/add_across_block_crash.ll
new file mode 100644
index 0000000..07be752
--- /dev/null
+++ b/test/Transforms/Reassociate/add_across_block_crash.ll
@@ -0,0 +1,20 @@
+; RUN: opt < %s -reassociate -S | FileCheck %s
+; CHECK-LABEL: main
+; This test is to make sure while processing a block, uses of instructions
+; from a different basic block don't get added to be re-optimized
+define void @main() {
+entry:
+ %0 = fadd fast float undef, undef
+ br i1 undef, label %bb1, label %bb2
+
+bb1:
+ %1 = fmul fast float undef, -2.000000e+00
+ %2 = fmul fast float %1, 2.000000e+00
+ %3 = fadd fast float %2, 2.000000e+00
+ %4 = fadd fast float %3, %0
+ %mul351 = fmul fast float %4, 5.000000e-01
+ ret void
+
+bb2:
+ ret void
+}
diff --git a/test/Transforms/RewriteStatepointsForGC/constants.ll b/test/Transforms/RewriteStatepointsForGC/constants.ll
index b30f64b..0f600f2 100644
--- a/test/Transforms/RewriteStatepointsForGC/constants.ll
+++ b/test/Transforms/RewriteStatepointsForGC/constants.ll
@@ -92,4 +92,13 @@ use:
ret i8 addrspace(1)* %res
}
-
+; Globals don't move and thus don't get relocated
+define i8 addrspace(1)* @test5(i1 %always_true) gc "statepoint-example" {
+; CHECK-LABEL: @test5
+; CHECK: gc.statepoint
+; CHECK-NEXT: %res = extractelement <2 x i8 addrspace(1)*> <i8 addrspace(1)* @G, i8 addrspace(1)* @G>, i32 0
+entry:
+ call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @foo, i32 0, i32 0, i32 0, i32 0)
+ %res = extractelement <2 x i8 addrspace(1)*> <i8 addrspace(1)* @G, i8 addrspace(1)* @G>, i32 0
+ ret i8 addrspace(1)* %res
+}
diff --git a/test/Transforms/RewriteStatepointsForGC/deopt-bundles/live-vector-nosplit.ll b/test/Transforms/RewriteStatepointsForGC/deopt-bundles/live-vector-nosplit.ll
new file mode 100644
index 0000000..ee578eb
--- /dev/null
+++ b/test/Transforms/RewriteStatepointsForGC/deopt-bundles/live-vector-nosplit.ll
@@ -0,0 +1,112 @@
+; Test that we can correctly handle vectors of pointers in statepoint
+; rewriting.
+; RUN: opt %s -rewrite-statepoints-for-gc -rs4gc-use-deopt-bundles -rs4gc-split-vector-values=0 -S | FileCheck %s
+
+; A non-vector relocation for comparison
+define i64 addrspace(1)* @test(i64 addrspace(1)* %obj) gc "statepoint-example" {
+; CHECK-LABEL: test
+; CHECK: gc.statepoint
+; CHECK-NEXT: gc.relocate
+; CHECK-NEXT: bitcast
+; CHECK-NEXT: ret i64 addrspace(1)*
+; A base vector from a argument
+entry:
+ call void @do_safepoint() [ "deopt"() ]
+ ret i64 addrspace(1)* %obj
+}
+
+; A vector argument
+define <2 x i64 addrspace(1)*> @test2(<2 x i64 addrspace(1)*> %obj) gc "statepoint-example" {
+; CHECK-LABEL: test2
+; CHECK-NEXT: gc.statepoint
+; CHECK-NEXT: gc.relocate
+; CHECK-NEXT: bitcast
+; CHECK-NEXT: ret <2 x i64 addrspace(1)*>
+ call void @do_safepoint() [ "deopt"() ]
+ ret <2 x i64 addrspace(1)*> %obj
+}
+
+; A load
+define <2 x i64 addrspace(1)*> @test3(<2 x i64 addrspace(1)*>* %ptr) gc "statepoint-example" {
+; CHECK-LABEL: test3
+; CHECK: load
+; CHECK-NEXT: gc.statepoint
+; CHECK-NEXT: gc.relocate
+; CHECK-NEXT: bitcast
+; CHECK-NEXT: ret <2 x i64 addrspace(1)*>
+entry:
+ %obj = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
+ call void @do_safepoint() [ "deopt"() ]
+ ret <2 x i64 addrspace(1)*> %obj
+}
+
+declare i32 @fake_personality_function()
+
+; When a statepoint is an invoke rather than a call
+define <2 x i64 addrspace(1)*> @test4(<2 x i64 addrspace(1)*>* %ptr) gc "statepoint-example" personality i32 ()* @fake_personality_function {
+; CHECK-LABEL: test4
+; CHECK: load
+; CHECK-NEXT: gc.statepoint
+entry:
+ %obj = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
+ invoke void @do_safepoint() [ "deopt"() ]
+ to label %normal_return unwind label %exceptional_return
+
+normal_return: ; preds = %entry
+; CHECK-LABEL: normal_return:
+; CHECK: gc.relocate
+; CHECK-NEXT: bitcast
+; CHECK-NEXT: ret <2 x i64 addrspace(1)*>
+ ret <2 x i64 addrspace(1)*> %obj
+
+exceptional_return: ; preds = %entry
+; CHECK-LABEL: exceptional_return:
+; CHECK: gc.relocate
+; CHECK-NEXT: bitcast
+; CHECK-NEXT: ret <2 x i64 addrspace(1)*>
+ %landing_pad4 = landingpad token
+ cleanup
+ ret <2 x i64 addrspace(1)*> %obj
+}
+
+; A newly created vector
+define <2 x i64 addrspace(1)*> @test5(i64 addrspace(1)* %p) gc "statepoint-example" {
+; CHECK-LABEL: test5
+; CHECK: insertelement
+; CHECK-NEXT: gc.statepoint
+; CHECK-NEXT: gc.relocate
+; CHECK-NEXT: bitcast
+; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %vec.relocated.casted
+entry:
+ %vec = insertelement <2 x i64 addrspace(1)*> undef, i64 addrspace(1)* %p, i32 0
+ call void @do_safepoint() [ "deopt"() ]
+ ret <2 x i64 addrspace(1)*> %vec
+}
+
+; A merge point
+define <2 x i64 addrspace(1)*> @test6(i1 %cnd, <2 x i64 addrspace(1)*>* %ptr) gc "statepoint-example" {
+; CHECK-LABEL: test6
+entry:
+ br i1 %cnd, label %taken, label %untaken
+
+taken: ; preds = %entry
+ %obja = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
+ br label %merge
+
+untaken: ; preds = %entry
+ %objb = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
+ br label %merge
+
+merge: ; preds = %untaken, %taken
+; CHECK-LABEL: merge:
+; CHECK-NEXT: = phi
+; CHECK-NEXT: gc.statepoint
+; CHECK-NEXT: gc.relocate
+; CHECK-NEXT: bitcast
+; CHECK-NEXT: ret <2 x i64 addrspace(1)*>
+ %obj = phi <2 x i64 addrspace(1)*> [ %obja, %taken ], [ %objb, %untaken ]
+ call void @do_safepoint() [ "deopt"() ]
+ ret <2 x i64 addrspace(1)*> %obj
+}
+
+declare void @do_safepoint()
diff --git a/test/Transforms/RewriteStatepointsForGC/deopt-bundles/live-vector.ll b/test/Transforms/RewriteStatepointsForGC/deopt-bundles/live-vector.ll
index 00f2893..284a993 100644
--- a/test/Transforms/RewriteStatepointsForGC/deopt-bundles/live-vector.ll
+++ b/test/Transforms/RewriteStatepointsForGC/deopt-bundles/live-vector.ll
@@ -1,6 +1,6 @@
; Test that we can correctly handle vectors of pointers in statepoint
; rewriting. Currently, we scalarize, but that's an implementation detail.
-; RUN: opt %s -rewrite-statepoints-for-gc -rs4gc-use-deopt-bundles -S | FileCheck %s
+; RUN: opt %s -rewrite-statepoints-for-gc -rs4gc-use-deopt-bundles -rs4gc-split-vector-values -S | FileCheck %s
; A non-vector relocation for comparison
diff --git a/test/Transforms/RewriteStatepointsForGC/live-vector.ll b/test/Transforms/RewriteStatepointsForGC/live-vector.ll
index 584fd7a..2ec09d6 100644
--- a/test/Transforms/RewriteStatepointsForGC/live-vector.ll
+++ b/test/Transforms/RewriteStatepointsForGC/live-vector.ll
@@ -1,6 +1,6 @@
; Test that we can correctly handle vectors of pointers in statepoint
; rewriting. Currently, we scalarize, but that's an implementation detail.
-; RUN: opt %s -rewrite-statepoints-for-gc -S | FileCheck %s
+; RUN: opt %s -rewrite-statepoints-for-gc -rs4gc-split-vector-values -S | FileCheck %s
; A non-vector relocation for comparison
define i64 addrspace(1)* @test(i64 addrspace(1)* %obj) gc "statepoint-example" {
diff --git a/test/Transforms/RewriteStatepointsForGC/two-invokes-one-landingpad.ll b/test/Transforms/RewriteStatepointsForGC/two-invokes-one-landingpad.ll
new file mode 100644
index 0000000..d3d3c5a
--- /dev/null
+++ b/test/Transforms/RewriteStatepointsForGC/two-invokes-one-landingpad.ll
@@ -0,0 +1,33 @@
+; RUN: opt %s -rewrite-statepoints-for-gc -rs4gc-use-deopt-bundles -S | FileCheck %s
+
+declare void @some_call(i64 addrspace(1)*)
+
+declare i32 @"dummy_personality_function"()
+
+define i64 addrspace(1)* @test(i64 addrspace(1)* %obj, i64 addrspace(1)* %obj1)
+ gc "statepoint-example"
+ personality i32 ()* @"dummy_personality_function" {
+entry:
+ invoke void @some_call(i64 addrspace(1)* %obj) [ "deopt"() ]
+ to label %second_invoke unwind label %exceptional_return
+
+second_invoke: ; preds = %entry
+ invoke void @some_call(i64 addrspace(1)* %obj) [ "deopt"() ]
+ to label %normal_return unwind label %exceptional_return
+
+normal_return: ; preds = %second_invoke
+ ret i64 addrspace(1)* %obj
+
+; CHECK: exceptional_return1:
+; CHECK-NEXT: %lpad2 = landingpad token
+
+; CHECK: exceptional_return.split-lp:
+; CHECK-NEXT: %lpad.split-lp = landingpad token
+
+; CHECK: exceptional_return:
+; CHECK-NOT: phi token
+
+exceptional_return: ; preds = %second_invoke, %entry
+ %lpad = landingpad token cleanup
+ ret i64 addrspace(1)* %obj1
+}
diff --git a/test/Transforms/SimplifyCFG/bug-25299.ll b/test/Transforms/SimplifyCFG/bug-25299.ll
new file mode 100644
index 0000000..706afbe
--- /dev/null
+++ b/test/Transforms/SimplifyCFG/bug-25299.ll
@@ -0,0 +1,40 @@
+; RUN: opt < %s -simplifycfg -S | FileCheck %s
+
+;; Test case for bug 25299, contributed by David Majnemer.
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @f(i1 %B) personality i1 undef {
+entry:
+;CHECK: entry
+;CHECK-NEXT: call void @g()
+ invoke void @g()
+ to label %continue unwind label %unwind
+
+unwind: ; preds = %entry
+ %tmp101 = landingpad { i8*, i32 }
+ cleanup
+ br i1 %B, label %resume, label %then
+
+then: ; preds = %cleanup1
+ br label %resume
+
+resume: ; preds = %cleanup2, %then, %cleanup1, %unwind
+ %tmp104 = phi { i8*, i32 } [ %tmp101, %then ], [ %tmp106, %cleanup2 ], [ %tmp101, %unwind ]
+;CHECK-NOT: resume { i8*, i32 } %tmp104
+ resume { i8*, i32 } %tmp104
+
+continue: ; preds = %entry, %continue
+;CHECK: continue: ; preds = %entry, %continue
+;CHECK-NEXT: call void @g()
+ invoke void @g()
+ to label %continue unwind label %cleanup2
+
+cleanup2: ; preds = %continue
+ %tmp106 = landingpad { i8*, i32 }
+ cleanup
+ br label %resume
+}
+
+declare void @g() \ No newline at end of file
diff --git a/test/Transforms/SimplifyCFG/invoke_unwind.ll b/test/Transforms/SimplifyCFG/invoke_unwind.ll
index 100bfd4..b11b7c1 100644
--- a/test/Transforms/SimplifyCFG/invoke_unwind.ll
+++ b/test/Transforms/SimplifyCFG/invoke_unwind.ll
@@ -30,4 +30,46 @@ Rethrow:
resume { i8*, i32 } %exn
}
+declare i64 @dummy1()
+declare i64 @dummy2()
+
+; This testcase checks to see if simplifycfg pass can convert two invoke
+; instructions to call instructions if they share a common trivial unwind
+; block.
+define i64 @test3(i1 %cond) personality i32 (...)* @__gxx_personality_v0 {
+entry:
+; CHECK-LABEL: @test3(
+; CHECK: %call1 = call i64 @dummy1()
+; CHECK: %call2 = call i64 @dummy2()
+; CHECK-NOT: resume { i8*, i32 } %lp
+ br i1 %cond, label %br1, label %br2
+
+br1:
+ %call1 = invoke i64 @dummy1()
+ to label %invoke.cont unwind label %lpad1
+
+br2:
+ %call2 = invoke i64 @dummy2()
+ to label %invoke.cont unwind label %lpad2
+
+invoke.cont:
+ %c = phi i64 [%call1, %br1], [%call2, %br2]
+ ret i64 %c
+
+
+lpad1:
+ %0 = landingpad { i8*, i32 }
+ cleanup
+ br label %rethrow
+
+rethrow:
+ %lp = phi { i8*, i32 } [%0, %lpad1], [%1, %lpad2]
+ resume { i8*, i32 } %lp
+
+lpad2:
+ %1 = landingpad { i8*, i32 }
+ cleanup
+ br label %rethrow
+}
+
declare i32 @__gxx_personality_v0(...)
diff --git a/test/Transforms/Util/split-bit-piece.ll b/test/Transforms/Util/split-bit-piece.ll
new file mode 100644
index 0000000..6945bec
--- /dev/null
+++ b/test/Transforms/Util/split-bit-piece.ll
@@ -0,0 +1,45 @@
+; Checks that llvm.dbg.declare -> llvm.dbg.value conversion utility
+; (here exposed through the SROA) pass, properly inserts bit_piece expressions
+; if it only describes part of the variable.
+; RUN: opt -S -sroa %s | FileCheck %s
+
+; Function Attrs: nounwind readnone
+declare void @llvm.dbg.declare(metadata, metadata, metadata) #0
+
+; Function Attrs: nounwind uwtable
+define hidden void @_ZN6__tsan9FastState14SetHistorySizeEi(i32 %hs) #1 align 2 {
+entry:
+ %hs.addr = alloca i32, align 4
+ %v1 = alloca i64, align 8
+ %v2 = alloca i64, align 8
+ store i32 %hs, i32* %hs.addr, align 4
+; CHECK: call void @llvm.dbg.value(metadata i32 %hs, i64 0, metadata !{{[0-9]+}}, metadata ![[EXPR:[0-9]+]])
+; CHECK: ![[EXPR]] = !DIExpression(DW_OP_bit_piece, 0
+ call void @llvm.dbg.declare(metadata i64* %v1, metadata !9, metadata !12), !dbg !13
+ %0 = load i32, i32* %hs.addr, align 4
+ %conv = sext i32 %0 to i64
+ store i64 %conv, i64* %v1, align 8
+ %1 = load i64, i64* %v2, align 8
+ unreachable
+}
+
+attributes #0 = { nounwind readnone }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!7}
+!llvm.ident = !{!8}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.8.0 (trunk 256979) (llvm/trunk 257107)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, retainedTypes: !2)
+!1 = !DIFile(filename: "tsan_shadow_test.cc", directory: "/tmp")
+!2 = !{!3, !5}
+!3 = !DICompositeType(tag: DW_TAG_class_type, name: "FastState", file: !4, line: 91, size: 64, align: 64, identifier: "_ZTSN6__tsan9FastStateE")
+!4 = !DIFile(filename: "/mnt/extra/llvm/projects/compiler-rt/lib/tsan/rtl/tsan_rtl.h", directory: "/tmp")
+!5 = distinct !DIDerivedType(tag: DW_TAG_typedef, name: "u64", line: 78, baseType: !6)
+!6 = !DIBasicType(name: "long long unsigned int", size: 64, align: 64, encoding: DW_ATE_unsigned)
+!7 = !{i32 2, !"Debug Info Version", i32 3}
+!8 = !{!"clang version 3.8.0 (trunk 256979) (llvm/trunk 257107)"}
+!9 = !DILocalVariable(name: "v1", scope: !10, file: !4, line: 136, type: !5)
+!10 = distinct !DILexicalBlock(scope: !11, file: !4, line: 136, column: 5)
+!11 = distinct !DISubprogram(name: "SetHistorySize", linkageName: "_ZN6__tsan9FastState14SetHistorySizeEi", scope: !"_ZTSN6__tsan9FastStateE", file: !4, line: 135, isLocal: false, isDefinition: true, scopeLine: 135, flags: DIFlagPrototyped, isOptimized: false)
+!12 = !DIExpression()
+!13 = !DILocation(line: 136, column: 5, scope: !10)
OpenPOWER on IntegriCloud