summaryrefslogtreecommitdiffstats
path: root/llvm/test/Transforms
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/test/Transforms')
-rw-r--r--llvm/test/Transforms/GVN/callbr-loadpre-critedge.ll49
-rw-r--r--llvm/test/Transforms/GVN/callbr-scalarpre-critedge.ll43
-rw-r--r--llvm/test/Transforms/JumpThreading/callbr-edge-split.ll58
-rw-r--r--llvm/test/Transforms/MergeFunc/call-and-invoke-with-ranges.ll15
-rw-r--r--llvm/test/Transforms/MergeFunc/inline-asm.ll6
5 files changed, 160 insertions, 11 deletions
diff --git a/llvm/test/Transforms/GVN/callbr-loadpre-critedge.ll b/llvm/test/Transforms/GVN/callbr-loadpre-critedge.ll
new file mode 100644
index 00000000000..2a6a0aa778a
--- /dev/null
+++ b/llvm/test/Transforms/GVN/callbr-loadpre-critedge.ll
@@ -0,0 +1,49 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -gvn -S | FileCheck %s
+
+; This test checks that we don't hang trying to split a critical edge in loadpre
+; when the control flow uses a callbr instruction.
+
+%struct.pluto = type <{ i8, i8 }>
+
+define void @widget(%struct.pluto** %tmp1) {
+; CHECK-LABEL: @widget(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: callbr void asm sideeffect "", "X,X"(i8* blockaddress(@widget, [[BB5:%.*]]), i8* blockaddress(@widget, [[BB8:%.*]]))
+; CHECK-NEXT: to label [[BB4:%.*]] [label [[BB5]], label %bb8]
+; CHECK: bb4:
+; CHECK-NEXT: br label [[BB5]]
+; CHECK: bb5:
+; CHECK-NEXT: [[TMP6:%.*]] = load %struct.pluto*, %struct.pluto** [[TMP1:%.*]]
+; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds [[STRUCT_PLUTO:%.*]], %struct.pluto* [[TMP6]], i64 0, i32 1
+; CHECK-NEXT: br label [[BB8]]
+; CHECK: bb8:
+; CHECK-NEXT: [[TMP9:%.*]] = phi i8* [ [[TMP7]], [[BB5]] ], [ null, [[BB:%.*]] ]
+; CHECK-NEXT: [[TMP10:%.*]] = load %struct.pluto*, %struct.pluto** [[TMP1]]
+; CHECK-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT_PLUTO]], %struct.pluto* [[TMP10]], i64 0, i32 0
+; CHECK-NEXT: [[TMP12:%.*]] = load i8, i8* [[TMP11]]
+; CHECK-NEXT: tail call void @spam(i8* [[TMP9]], i8 [[TMP12]])
+; CHECK-NEXT: ret void
+;
+bb:
+ callbr void asm sideeffect "", "X,X"(i8* blockaddress(@widget, %bb5), i8* blockaddress(@widget, %bb8))
+ to label %bb4 [label %bb5, label %bb8]
+
+bb4: ; preds = %bb
+ br label %bb5
+
+bb5: ; preds = %bb4, %bb
+ %tmp6 = load %struct.pluto*, %struct.pluto** %tmp1
+ %tmp7 = getelementptr inbounds %struct.pluto, %struct.pluto* %tmp6, i64 0, i32 1
+ br label %bb8
+
+bb8: ; preds = %bb5, %bb
+ %tmp9 = phi i8* [ %tmp7, %bb5 ], [ null, %bb ]
+ %tmp10 = load %struct.pluto*, %struct.pluto** %tmp1
+ %tmp11 = getelementptr inbounds %struct.pluto, %struct.pluto* %tmp10, i64 0, i32 0
+ %tmp12 = load i8, i8* %tmp11
+ tail call void @spam(i8* %tmp9, i8 %tmp12)
+ ret void
+}
+
+declare void @spam(i8*, i8)
diff --git a/llvm/test/Transforms/GVN/callbr-scalarpre-critedge.ll b/llvm/test/Transforms/GVN/callbr-scalarpre-critedge.ll
new file mode 100644
index 00000000000..733ba4a0cc8
--- /dev/null
+++ b/llvm/test/Transforms/GVN/callbr-scalarpre-critedge.ll
@@ -0,0 +1,43 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -gvn -S | FileCheck %s
+
+; This test checks that we don't hang trying to split a critical edge in scalar
+; PRE when the control flow uses a callbr instruction.
+
+define void @wombat(i64 %arg, i64* %arg1, i64 %arg2, i32* %arg3) {
+; CHECK-LABEL: @wombat(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[TMP5:%.*]] = or i64 [[ARG2:%.*]], [[ARG:%.*]]
+; CHECK-NEXT: callbr void asm sideeffect "", "X,X"(i8* blockaddress(@wombat, [[BB7:%.*]]), i8* blockaddress(@wombat, [[BB9:%.*]]))
+; CHECK-NEXT: to label [[BB6:%.*]] [label [[BB7]], label %bb9]
+; CHECK: bb6:
+; CHECK-NEXT: br label [[BB7]]
+; CHECK: bb7:
+; CHECK-NEXT: [[TMP8:%.*]] = trunc i64 [[TMP5]] to i32
+; CHECK-NEXT: tail call void @barney(i32 [[TMP8]])
+; CHECK-NEXT: br label [[BB9]]
+; CHECK: bb9:
+; CHECK-NEXT: [[TMP10:%.*]] = trunc i64 [[TMP5]] to i32
+; CHECK-NEXT: store i32 [[TMP10]], i32* [[ARG3:%.*]]
+; CHECK-NEXT: ret void
+;
+bb:
+ %tmp5 = or i64 %arg2, %arg
+ callbr void asm sideeffect "", "X,X"(i8* blockaddress(@wombat, %bb7), i8* blockaddress(@wombat, %bb9))
+ to label %bb6 [label %bb7, label %bb9]
+
+bb6: ; preds = %bb
+ br label %bb7
+
+bb7: ; preds = %bb6, %bb
+ %tmp8 = trunc i64 %tmp5 to i32
+ tail call void @barney(i32 %tmp8)
+ br label %bb9
+
+bb9: ; preds = %bb7, %bb
+ %tmp10 = trunc i64 %tmp5 to i32
+ store i32 %tmp10, i32* %arg3
+ ret void
+}
+
+declare void @barney(i32)
diff --git a/llvm/test/Transforms/JumpThreading/callbr-edge-split.ll b/llvm/test/Transforms/JumpThreading/callbr-edge-split.ll
new file mode 100644
index 00000000000..a341f73dee5
--- /dev/null
+++ b/llvm/test/Transforms/JumpThreading/callbr-edge-split.ll
@@ -0,0 +1,58 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -S -jump-threading | FileCheck %s
+
+; This test used to cause jump threading to try to split an edge of a callbr.
+
+@a = global i32 0
+
+define i32 @c() {
+; CHECK-LABEL: @c(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a
+; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP0]], 0
+; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
+; CHECK: if.then:
+; CHECK-NEXT: [[CALL:%.*]] = call i32 @b()
+; CHECK-NEXT: [[PHITMP:%.*]] = icmp ne i32 [[CALL]], 0
+; CHECK-NEXT: br i1 [[PHITMP]], label [[IF_THEN2:%.*]], label [[IF_END4:%.*]]
+; CHECK: if.else:
+; CHECK-NEXT: callbr void asm sideeffect "", "X"(i8* blockaddress(@c, [[IF_THEN2]]))
+; CHECK-NEXT: to label [[IF_END_THREAD:%.*]] [label %if.then2]
+; CHECK: if.end.thread:
+; CHECK-NEXT: br label [[IF_THEN2]]
+; CHECK: if.then2:
+; CHECK-NEXT: [[CALL3:%.*]] = call i32 @b()
+; CHECK-NEXT: br label [[IF_END4]]
+; CHECK: if.end4:
+; CHECK-NEXT: ret i32 undef
+;
+entry:
+ %0 = load i32, i32* @a
+ %tobool = icmp eq i32 %0, 0
+ br i1 %tobool, label %if.else, label %if.then
+
+if.then: ; preds = %entry
+ %call = call i32 @b() #2
+ %phitmp = icmp ne i32 %call, 0
+ br label %if.end
+
+if.else: ; preds = %entry
+ callbr void asm sideeffect "", "X"(i8* blockaddress(@c, %if.end)) #2
+ to label %normal [label %if.end]
+
+normal: ; preds = %if.else
+ br label %if.end
+
+if.end: ; preds = %if.else, %normal, %if.then
+ %d.0 = phi i1 [ %phitmp, %if.then ], [ undef, %normal ], [ undef, %if.else ]
+ br i1 %d.0, label %if.then2, label %if.end4
+
+if.then2: ; preds = %if.end
+ %call3 = call i32 @b()
+ br label %if.end4
+
+if.end4: ; preds = %if.then2, %if.end
+ ret i32 undef
+}
+
+declare i32 @b()
diff --git a/llvm/test/Transforms/MergeFunc/call-and-invoke-with-ranges.ll b/llvm/test/Transforms/MergeFunc/call-and-invoke-with-ranges.ll
index f138ac42914..4b8d6bb53e4 100644
--- a/llvm/test/Transforms/MergeFunc/call-and-invoke-with-ranges.ll
+++ b/llvm/test/Transforms/MergeFunc/call-and-invoke-with-ranges.ll
@@ -63,14 +63,6 @@ lpad:
resume { i8*, i32 } zeroinitializer
}
-define i8 @call_with_same_range() {
-; CHECK-LABEL: @call_with_same_range
-; CHECK: tail call i8 @call_with_range
- bitcast i8 0 to i8
- %out = call i8 @dummy(), !range !0
- ret i8 %out
-}
-
define i8 @invoke_with_same_range() personality i8* undef {
; CHECK-LABEL: @invoke_with_same_range()
; CHECK: tail call i8 @invoke_with_range()
@@ -84,6 +76,13 @@ lpad:
resume { i8*, i32 } zeroinitializer
}
+define i8 @call_with_same_range() {
+; CHECK-LABEL: @call_with_same_range
+; CHECK: tail call i8 @call_with_range
+ bitcast i8 0 to i8
+ %out = call i8 @dummy(), !range !0
+ ret i8 %out
+}
declare i8 @dummy();
diff --git a/llvm/test/Transforms/MergeFunc/inline-asm.ll b/llvm/test/Transforms/MergeFunc/inline-asm.ll
index 370d3c56f06..15760242cf6 100644
--- a/llvm/test/Transforms/MergeFunc/inline-asm.ll
+++ b/llvm/test/Transforms/MergeFunc/inline-asm.ll
@@ -3,13 +3,13 @@
; CHECK-LABEL: @int_ptr_arg_different
; CHECK-NEXT: call void asm
+; CHECK-LABEL: @int_ptr_null
+; CHECK-NEXT: tail call void @float_ptr_null()
+
; CHECK-LABEL: @int_ptr_arg_same
; CHECK-NEXT: %2 = bitcast i32* %0 to float*
; CHECK-NEXT: tail call void @float_ptr_arg_same(float* %2)
-; CHECK-LABEL: @int_ptr_null
-; CHECK-NEXT: tail call void @float_ptr_null()
-
; Used to satisfy minimum size limit
declare void @stuff()
OpenPOWER on IntegriCloud