summaryrefslogtreecommitdiffstats
path: root/llvm/test
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/test')
-rw-r--r--llvm/test/Transforms/FunctionAttrs/arg_returned.ll2
-rw-r--r--llvm/test/Transforms/FunctionAttrs/liveness.ll97
-rw-r--r--llvm/test/Transforms/FunctionAttrs/willreturn.ll7
3 files changed, 64 insertions, 42 deletions
diff --git a/llvm/test/Transforms/FunctionAttrs/arg_returned.ll b/llvm/test/Transforms/FunctionAttrs/arg_returned.ll
index a5699fc1fc0..f7d1de0f5d9 100644
--- a/llvm/test/Transforms/FunctionAttrs/arg_returned.ll
+++ b/llvm/test/Transforms/FunctionAttrs/arg_returned.ll
@@ -748,4 +748,6 @@ attributes #0 = { noinline nounwind uwtable }
; BOTH-DAG: attributes #{{[0-9]*}} = { nofree noinline nosync nounwind readnone uwtable }
; BOTH-DAG: attributes #{{[0-9]*}} = { nofree noinline nosync nounwind readonly uwtable }
; BOTH-DAG: attributes #{{[0-9]*}} = { noinline nounwind uwtable }
+; BOTH-DAG: attributes #{{[0-9]*}} = { nofree noinline nosync nounwind readnone uwtable willreturn }
+; BOTH-DAG: attributes #{{[0-9]*}} = { nofree noinline nosync nounwind uwtable willreturn }
; BOTH-NOT: attributes #
diff --git a/llvm/test/Transforms/FunctionAttrs/liveness.ll b/llvm/test/Transforms/FunctionAttrs/liveness.ll
index 1de005d15c5..42ef89cfe8a 100644
--- a/llvm/test/Transforms/FunctionAttrs/liveness.ll
+++ b/llvm/test/Transforms/FunctionAttrs/liveness.ll
@@ -1,21 +1,67 @@
; RUN: opt -attributor --attributor-disable=false -S < %s | FileCheck %s
-declare void @no_return_call() noreturn
+declare void @no_return_call() nofree noreturn nounwind readnone
-declare void @normal_call()
+declare void @normal_call() readnone
declare i32 @foo()
declare i32 @foo_noreturn() noreturn
-declare i32 @bar()
+declare i32 @bar() nosync readnone
-; TEST 1: cond.true is dead, but cond.end is not, since cond.false is live
+; CHECK: Function Attrs: nofree norecurse nounwind uwtable willreturn
+define i32 @volatile_load(i32*) norecurse nounwind uwtable {
+ %2 = load volatile i32, i32* %0, align 4
+ ret i32 %2
+}
+
+; CHECK: Function Attrs: nofree norecurse nosync nounwind uwtable willreturn
+; CHECK-NEXT: define internal i32 @internal_load(i32* nonnull)
+define internal i32 @internal_load(i32*) norecurse nounwind uwtable {
+ %2 = load i32, i32* %0, align 4
+ ret i32 %2
+}
+; TEST 1: Only first block is live.
+
+; CHECK: Function Attrs: nofree nosync nounwind
+; CHECK-NEXT: define i32 @first_block_no_return(i32 %a, i32* nonnull %ptr1, i32* %ptr2)
+define i32 @first_block_no_return(i32 %a, i32* nonnull %ptr1, i32* %ptr2) #0 {
+entry:
+ call i32 @internal_load(i32* %ptr1)
+ ; CHECK: call i32 @internal_load(i32* nonnull %ptr1)
+ call void @no_return_call()
+ ; CHECK: call void @no_return_call()
+ ; CHECK-NEXT: unreachable
+ %cmp = icmp eq i32 %a, 0
+ br i1 %cmp, label %cond.true, label %cond.false
+
+cond.true: ; preds = %entry
+ call i32 @internal_load(i32* %ptr2)
+ ; CHECK: call i32 @internal_load(i32* %ptr2)
+ %load = call i32 @volatile_load(i32* %ptr1)
+ call void @normal_call()
+ %call = call i32 @foo()
+ br label %cond.end
+
+cond.false: ; preds = %entry
+ call void @normal_call()
+ %call1 = call i32 @bar()
+ br label %cond.end
+
+cond.end: ; preds = %cond.false, %cond.true
+ %cond = phi i32 [ %call, %cond.true ], [ %call1, %cond.false ]
+ ret i32 %cond
+}
+
+; TEST 2: cond.true is dead, but cond.end is not, since cond.false is live
; This is just an example. For example we can put a sync call in a
; dead block and check if it is deduced.
-define i32 @dead_block_present(i32 %a) #0 {
+; CHECK: Function Attrs: nosync
+; CHECK-NEXT: define i32 @dead_block_present(i32 %a, i32* %ptr1)
+define i32 @dead_block_present(i32 %a, i32* %ptr1) #0 {
entry:
%cmp = icmp eq i32 %a, 0
br i1 %cmp, label %cond.true, label %cond.false
@@ -24,7 +70,7 @@ cond.true: ; preds = %entry
call void @no_return_call()
; CHECK: call void @no_return_call()
; CHECK-NEXT: unreachable
- %call = call i32 @foo()
+ %call = call i32 @volatile_load(i32* %ptr1)
br label %cond.end
cond.false: ; preds = %entry
@@ -37,7 +83,7 @@ cond.end: ; preds = %cond.false, %cond.t
ret i32 %cond
}
-; TEST 2: both cond.true and cond.false are dead, therfore cond.end is dead as well.
+; TEST 3: both cond.true and cond.false are dead, therfore cond.end is dead as well.
define i32 @all_dead(i32 %a) #0 {
entry:
@@ -65,7 +111,7 @@ cond.end: ; preds = %cond.false, %cond.t
declare i32 @__gxx_personality_v0(...)
-; TEST 3: All blocks are live.
+; TEST 4: All blocks are live.
; CHECK: define i32 @all_live(i32 %a)
define i32 @all_live(i32 %a) #0 {
@@ -88,7 +134,7 @@ cond.end: ; preds = %cond.false, %cond.t
ret i32 %cond
}
-; TEST 4 noreturn invoke instruction replaced by a call and an unreachable instruction
+; TEST 5 noreturn invoke instruction replaced by a call and an unreachable instruction
; put after it.
; CHECK: define i32 @invoke_noreturn(i32 %a)
@@ -122,7 +168,7 @@ cleanup:
ret i32 0
}
-; TEST 5: Undefined behvior, taken from LangRef.
+; TEST 6: Undefined behvior, taken from LangRef.
; FIXME: Should be able to detect undefined behavior.
; CHECK define @ub(i32)
@@ -142,7 +188,7 @@ while.body: ; preds = %entry, %while.body
br label %while.body
}
-; TEST 6: Infinite loop.
+; TEST 7: Infinite loop.
; FIXME: Detect infloops, and mark affected blocks dead.
define i32 @test5(i32, i32) #0 {
@@ -173,7 +219,7 @@ entry:
ret void
}
-; TEST 7: Recursion
+; TEST 8: Recursion
; FIXME: everything after first block should be marked dead
; and unreachable should be put after call to @rec().
@@ -199,7 +245,7 @@ cond.end: ; preds = %cond.if, %con
%7 = phi i32 [ %1, %cond.elseif ], [ 0, %cond.else ], [ 0, %cond.if ]
ret i32 %7
}
-; TEST 8: Recursion
+; TEST 9: Recursion
; FIXME: contains recursive call to itself in cond.elseif block
define i32 @test7(i32, i32) #0 {
@@ -223,28 +269,3 @@ cond.end: ; preds = %cond.if, %con
%8 = phi i32 [ %1, %cond.elseif ], [ 0, %cond.else ], [ 0, %cond.if ]
ret i32 %8
}
-
-; TEST 9: Only first block is live.
-
-define i32 @first_block_no_return(i32 %a) #0 {
-entry:
- call void @no_return_call()
- ; CHECK: call void @no_return_call()
- ; CHECK-NEXT: unreachable
- %cmp = icmp eq i32 %a, 0
- br i1 %cmp, label %cond.true, label %cond.false
-
-cond.true: ; preds = %entry
- call void @normal_call()
- %call = call i32 @foo()
- br label %cond.end
-
-cond.false: ; preds = %entry
- call void @normal_call()
- %call1 = call i32 @bar()
- br label %cond.end
-
-cond.end: ; preds = %cond.false, %cond.true
- %cond = phi i32 [ %call, %cond.true ], [ %call1, %cond.false ]
- ret i32 %cond
-}
diff --git a/llvm/test/Transforms/FunctionAttrs/willreturn.ll b/llvm/test/Transforms/FunctionAttrs/willreturn.ll
index e2b76b156ea..eb1dbb1342c 100644
--- a/llvm/test/Transforms/FunctionAttrs/willreturn.ll
+++ b/llvm/test/Transforms/FunctionAttrs/willreturn.ll
@@ -454,10 +454,9 @@ f:
; unreachable exit
; 15.1 (positive case)
-; FIXME: missing willreturn
; FNATTR: Function Attrs: noinline nounwind uwtable
; FNATTR-NEXT: define void @unreachable_exit_positive1()
-; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
+; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable willreturn
; ATTRIBUTOR-NEXT: define void @unreachable_exit_positive1()
define void @unreachable_exit_positive1() #0 {
tail call void @will_return()
@@ -471,7 +470,7 @@ unreachable_label:
; FIXME: missing willreturn
; FNATTR: Function Attrs: noinline nounwind uwtable
; FNATTR-NEXT: define i32 @unreachable_exit_positive2(i32)
-; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
+; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind uwtable
; ATTRIBUTOR-NEXT: define i32 @unreachable_exit_positive2(i32)
define i32 @unreachable_exit_positive2(i32) local_unnamed_addr #0 {
%2 = icmp slt i32 %0, 1
@@ -515,7 +514,7 @@ unreachable_label:
; FNATTR: Function Attrs: noinline nounwind uwtable
; FNATTR-NOT: willreturn
; FNATTR-NEXT: define void @unreachable_exit_negative2()
-; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
+; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind uwtable
; ATTRIBUTOR-NOT: willreturn
; ATTRIBUTOR-NEXT: define void @unreachable_exit_negative2()
define void @unreachable_exit_negative2() #0 {
OpenPOWER on IntegriCloud