diff options
Diffstat (limited to 'llvm/test/Transforms')
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() |

