From 86126dbc15c5110a9604814ae6f23afd1b2df72e Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 13 Oct 2022 11:16:24 +0200 Subject: [PATCH] [FunctionAttrs] Regenerate test checks (NFC) --- .../FunctionAttrs/incompatible_fn_attrs.ll | 27 +++-- llvm/test/Transforms/FunctionAttrs/nounwind.ll | 66 ++++++++--- .../FunctionAttrs/operand-bundles-scc.ll | 27 +++-- .../Transforms/FunctionAttrs/read-write-scc.ll | 20 +++- llvm/test/Transforms/FunctionAttrs/willreturn.ll | 118 ++++++++++++++----- llvm/test/Transforms/FunctionAttrs/writeonly.ll | 126 +++++++++++++++++---- 6 files changed, 294 insertions(+), 90 deletions(-) diff --git a/llvm/test/Transforms/FunctionAttrs/incompatible_fn_attrs.ll b/llvm/test/Transforms/FunctionAttrs/incompatible_fn_attrs.ll index 073fb97..b2b46f6 100644 --- a/llvm/test/Transforms/FunctionAttrs/incompatible_fn_attrs.ll +++ b/llvm/test/Transforms/FunctionAttrs/incompatible_fn_attrs.ll @@ -1,26 +1,35 @@ -; RUN: opt -S -o - -function-attrs %s | FileCheck %s -; RUN: opt -S -o - -passes=function-attrs %s | FileCheck %s +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes +; RUN: opt -S -o - -passes=function-attrs < %s | FileCheck %s ; Verify we remove argmemonly/inaccessiblememonly/inaccessiblemem_or_argmemonly ; function attributes when we derive readnone. -; Function Attrs: argmemonly define ptr @given_argmem_infer_readnone(ptr %p) #0 { -; CHECK: define ptr @given_argmem_infer_readnone(ptr readnone returned %p) #0 { +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +; CHECK-LABEL: @given_argmem_infer_readnone( +; CHECK-NEXT: entry: +; CHECK-NEXT: ret ptr [[P:%.*]] +; entry: ret ptr %p } -; Function Attrs: inaccessiblememonly define ptr @given_inaccessible_infer_readnone(ptr %p) #1 { -; CHECK: define ptr @given_inaccessible_infer_readnone(ptr readnone returned %p) #0 { +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +; CHECK-LABEL: @given_inaccessible_infer_readnone( +; CHECK-NEXT: entry: +; CHECK-NEXT: ret ptr [[P:%.*]] +; entry: ret ptr %p } -; Function Attrs: inaccessiblemem_or_argmemonly define ptr @given_inaccessible_or_argmem_infer_readnone(ptr %p) #2 { -; CHECK: define ptr @given_inaccessible_or_argmem_infer_readnone(ptr readnone returned %p) #0 { +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +; CHECK-LABEL: @given_inaccessible_or_argmem_infer_readnone( +; CHECK-NEXT: entry: +; CHECK-NEXT: ret ptr [[P:%.*]] +; entry: ret ptr %p } @@ -28,5 +37,3 @@ entry: attributes #0 = { argmemonly } attributes #1 = { inaccessiblememonly } attributes #2 = { inaccessiblemem_or_argmemonly } -; CHECK: attributes #0 = { mustprogress nofree norecurse nosync nounwind readnone willreturn } -; CHECK-NOT: attributes diff --git a/llvm/test/Transforms/FunctionAttrs/nounwind.ll b/llvm/test/Transforms/FunctionAttrs/nounwind.ll index 0b357c9..7987f74 100644 --- a/llvm/test/Transforms/FunctionAttrs/nounwind.ll +++ b/llvm/test/Transforms/FunctionAttrs/nounwind.ll @@ -1,37 +1,51 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes ; RUN: opt < %s -function-attrs -S | FileCheck %s ; TEST 1 -; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone -; CHECK-NEXT: define i32 @foo1() define i32 @foo1() { +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +; CHECK-LABEL: define {{[^@]+}}@foo1 +; CHECK-SAME: () #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: ret i32 1 +; ret i32 1 } ; TEST 2 -; CHECK: Function Attrs: nofree nosync nounwind readnone -; CHECK-NEXT: define i32 @scc1_foo() define i32 @scc1_foo() { +; CHECK: Function Attrs: nofree nosync nounwind readnone +; CHECK-LABEL: define {{[^@]+}}@scc1_foo +; CHECK-SAME: () #[[ATTR1:[0-9]+]] { +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @scc1_bar() +; CHECK-NEXT: ret i32 1 +; %1 = call i32 @scc1_bar() ret i32 1 } ; TEST 3 -; CHECK: Function Attrs: nofree nosync nounwind readnone -; CHECK-NEXT: define i32 @scc1_bar() define i32 @scc1_bar() { +; CHECK: Function Attrs: nofree nosync nounwind readnone +; CHECK-LABEL: define {{[^@]+}}@scc1_bar +; CHECK-SAME: () #[[ATTR1]] { +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @scc1_foo() +; CHECK-NEXT: ret i32 1 +; %1 = call i32 @scc1_foo() ret i32 1 } -; CHECK: declare i32 @non_nounwind() declare i32 @non_nounwind() ; TEST 4 -; CHECK: define void @call_non_nounwind() { define void @call_non_nounwind(){ - tail call i32 @non_nounwind() - ret void +; CHECK-LABEL: define {{[^@]+}}@call_non_nounwind() { +; CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @non_nounwind() +; CHECK-NEXT: ret void +; + tail call i32 @non_nounwind() + ret void } ; TEST 5 - throw @@ -42,8 +56,16 @@ define void @call_non_nounwind(){ ; return -1; ; } -; CHECK: define i32 @maybe_throw(i1 zeroext %0) define i32 @maybe_throw(i1 zeroext %0) { +; CHECK-LABEL: define {{[^@]+}}@maybe_throw +; CHECK-SAME: (i1 zeroext [[TMP0:%.*]]) { +; CHECK-NEXT: br i1 [[TMP0]], label [[TMP2:%.*]], label [[TMP3:%.*]] +; CHECK: 2: +; CHECK-NEXT: tail call void @__cxa_rethrow() +; CHECK-NEXT: unreachable +; CHECK: 3: +; CHECK-NEXT: ret i32 -1 +; br i1 %0, label %2, label %3 2: ; preds = %1 @@ -65,17 +87,29 @@ declare void @__cxa_rethrow() ; return 1; ; } -; CHECK: define i32 @catch_thing() define i32 @catch_thing() personality ptr @__gxx_personality_v0 { +; CHECK-LABEL: define {{[^@]+}}@catch_thing() personality ptr @__gxx_personality_v0 { +; CHECK-NEXT: invoke void @__cxa_rethrow() +; CHECK-NEXT: to label [[TMP1:%.*]] unwind label [[TMP2:%.*]] +; CHECK: 1: +; CHECK-NEXT: unreachable +; CHECK: 2: +; CHECK-NEXT: [[TMP3:%.*]] = landingpad { ptr, i32 } +; CHECK-NEXT: catch ptr null +; CHECK-NEXT: [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP3]], 0 +; CHECK-NEXT: [[TMP5:%.*]] = tail call ptr @__cxa_begin_catch(ptr [[TMP4]]) +; CHECK-NEXT: tail call void @__cxa_end_catch() +; CHECK-NEXT: ret i32 -1 +; invoke void @__cxa_rethrow() #1 - to label %1 unwind label %2 + to label %1 unwind label %2 1: ; preds = %0 unreachable 2: ; preds = %0 %3 = landingpad { ptr, i32 } - catch ptr null + catch ptr null %4 = extractvalue { ptr, i32 } %3, 0 %5 = tail call ptr @__cxa_begin_catch(ptr %4) #2 tail call void @__cxa_end_catch() @@ -83,6 +117,10 @@ define i32 @catch_thing() personality ptr @__gxx_personality_v0 { } define i32 @catch_thing_user() { +; CHECK-LABEL: define {{[^@]+}}@catch_thing_user() { +; CHECK-NEXT: [[CATCH_THING_CALL:%.*]] = call i32 @catch_thing() +; CHECK-NEXT: ret i32 [[CATCH_THING_CALL]] +; %catch_thing_call = call i32 @catch_thing() ret i32 %catch_thing_call } diff --git a/llvm/test/Transforms/FunctionAttrs/operand-bundles-scc.ll b/llvm/test/Transforms/FunctionAttrs/operand-bundles-scc.ll index 92384a6..c1aa14b 100644 --- a/llvm/test/Transforms/FunctionAttrs/operand-bundles-scc.ll +++ b/llvm/test/Transforms/FunctionAttrs/operand-bundles-scc.ll @@ -1,17 +1,24 @@ -; RUN: opt -S -function-attrs < %s | FileCheck %s +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes ; RUN: opt -S -passes=function-attrs < %s | FileCheck %s define void @f() { -; CHECK-LABEL: define void @f() #0 { - call void @g() [ "unknown"() ] - ret void +; CHECK: Function Attrs: nofree nosync nounwind +; CHECK-LABEL: define {{[^@]+}}@f +; CHECK-SAME: () #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: call void @g() [ "unknown"() ] +; CHECK-NEXT: ret void +; + call void @g() [ "unknown"() ] + ret void } define void @g() { -; CHECK-LABEL: define void @g() #0 { - call void @f() - ret void +; CHECK: Function Attrs: nofree nosync nounwind +; CHECK-LABEL: define {{[^@]+}}@g +; CHECK-SAME: () #[[ATTR0]] { +; CHECK-NEXT: call void @f() +; CHECK-NEXT: ret void +; + call void @f() + ret void } - - -; CHECK: attributes #0 = { nofree nosync nounwind } diff --git a/llvm/test/Transforms/FunctionAttrs/read-write-scc.ll b/llvm/test/Transforms/FunctionAttrs/read-write-scc.ll index 788570c..3640eb5 100644 --- a/llvm/test/Transforms/FunctionAttrs/read-write-scc.ll +++ b/llvm/test/Transforms/FunctionAttrs/read-write-scc.ll @@ -1,20 +1,30 @@ -; RUN: opt -S -function-attrs < %s | FileCheck %s +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes ; RUN: opt -S -passes=function-attrs < %s | FileCheck %s @i = global i32 0 define void @foo() { -; CHECK-LABEL: define void @foo() #0 { +; CHECK: Function Attrs: nofree nosync nounwind +; CHECK-LABEL: define {{[^@]+}}@foo +; CHECK-SAME: () #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: store i32 1, ptr @i, align 4 +; CHECK-NEXT: call void @bar() +; CHECK-NEXT: ret void +; store i32 1, ptr @i call void @bar() ret void } define void @bar() { -; CHECK-LABEL: define void @bar() #0 { +; CHECK: Function Attrs: nofree nosync nounwind +; CHECK-LABEL: define {{[^@]+}}@bar +; CHECK-SAME: () #[[ATTR0]] { +; CHECK-NEXT: [[I:%.*]] = load i32, ptr @i, align 4 +; CHECK-NEXT: call void @foo() +; CHECK-NEXT: ret void +; %i = load i32, ptr @i call void @foo() ret void } - -; CHECK: attributes #0 = { nofree nosync nounwind } diff --git a/llvm/test/Transforms/FunctionAttrs/willreturn.ll b/llvm/test/Transforms/FunctionAttrs/willreturn.ll index f45f59f..3413b96 100644 --- a/llvm/test/Transforms/FunctionAttrs/willreturn.ll +++ b/llvm/test/Transforms/FunctionAttrs/willreturn.ll @@ -1,8 +1,13 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes ; RUN: opt -function-attrs -S %s | FileCheck %s define void @mustprogress_readnone() mustprogress { -; CHECK: Function Attrs: {{.*}} noreturn {{.*}} readnone willreturn -; CHECK-NEXT: define void @mustprogress_readnone() +; CHECK: Function Attrs: mustprogress nofree norecurse noreturn nosync nounwind readnone willreturn +; CHECK-LABEL: @mustprogress_readnone( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[WHILE_BODY:%.*]] +; CHECK: while.body: +; CHECK-NEXT: br label [[WHILE_BODY]] ; entry: br label %while.body @@ -12,8 +17,13 @@ while.body: } define i32 @mustprogress_load(ptr %ptr) mustprogress { -; CHECK: Function Attrs: {{.*}} readonly willreturn -; CHECK-NEXT: define i32 @mustprogress_load( +; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse noreturn nosync nounwind readonly willreturn +; CHECK-LABEL: @mustprogress_load( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[WHILE_BODY:%.*]] +; CHECK: while.body: +; CHECK-NEXT: [[R:%.*]] = load i32, ptr [[PTR:%.*]], align 4 +; CHECK-NEXT: br label [[WHILE_BODY]] ; entry: br label %while.body @@ -24,8 +34,13 @@ while.body: } define void @mustprogress_store(ptr %ptr) mustprogress { -; CHECK-NOT: Function Attrs: {{.*}} willreturn -; CHECK: define void @mustprogress_store( +; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse noreturn nosync nounwind writeonly +; CHECK-LABEL: @mustprogress_store( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[WHILE_BODY:%.*]] +; CHECK: while.body: +; CHECK-NEXT: store i32 0, ptr [[PTR:%.*]], align 4 +; CHECK-NEXT: br label [[WHILE_BODY]] ; entry: br label %while.body @@ -38,16 +53,21 @@ while.body: declare void @unknown_fn() define void @mustprogress_call_unknown_fn() mustprogress { -; CHECK-NOT: Function Attrs: {{.*}} willreturn -; CHECK: define void @mustprogress_call_unknown_fn( +; CHECK: Function Attrs: mustprogress +; CHECK-LABEL: @mustprogress_call_unknown_fn( +; CHECK-NEXT: call void @unknown_fn() +; CHECK-NEXT: ret void ; call void @unknown_fn() ret void } define i32 @mustprogress_call_known_functions(ptr %ptr) mustprogress { -; CHECK: Function Attrs: {{.*}} readonly willreturn -; CHECK-NEXT: define i32 @mustprogress_call_known_functions( +; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse noreturn nosync nounwind readonly willreturn +; CHECK-LABEL: @mustprogress_call_known_functions( +; CHECK-NEXT: call void @mustprogress_readnone() +; CHECK-NEXT: [[R:%.*]] = call i32 @mustprogress_load(ptr [[PTR:%.*]]) +; CHECK-NEXT: ret i32 [[R]] ; call void @mustprogress_readnone() %r = call i32 @mustprogress_load(ptr %ptr) @@ -57,24 +77,42 @@ define i32 @mustprogress_call_known_functions(ptr %ptr) mustprogress { declare i32 @__gxx_personality_v0(...) define i64 @mustprogress_mayunwind() mustprogress personality ptr @__gxx_personality_v0 { -; CHECK: Function Attrs: {{.*}} readnone willreturn -; CHECK-NEXT: define i64 @mustprogress_mayunwind( +; CHECK: Function Attrs: mustprogress nofree nosync nounwind readnone willreturn +; CHECK-LABEL: @mustprogress_mayunwind( +; CHECK-NEXT: [[A:%.*]] = invoke i64 @fn_noread() +; CHECK-NEXT: to label [[A:%.*]] unwind label [[B:%.*]] +; CHECK: A: +; CHECK-NEXT: ret i64 10 +; CHECK: B: +; CHECK-NEXT: [[VAL:%.*]] = landingpad { ptr, i32 } +; CHECK-NEXT: catch ptr null +; CHECK-NEXT: ret i64 0 ; %a = invoke i64 @fn_noread() - to label %A unwind label %B + to label %A unwind label %B A: ret i64 10 B: %val = landingpad { ptr, i32 } - catch ptr null + catch ptr null ret i64 0 } ; Function without loops or non-willreturn calls will return. define void @willreturn_no_loop(i1 %c, ptr %p) { ; CHECK: Function Attrs: mustprogress willreturn -; CHECK-NEXT: define void @willreturn_no_loop( +; CHECK-LABEL: @willreturn_no_loop( +; CHECK-NEXT: br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]] +; CHECK: if: +; CHECK-NEXT: [[TMP1:%.*]] = load atomic i32, ptr [[P:%.*]] seq_cst, align 4 +; CHECK-NEXT: call void @fn_willreturn() +; CHECK-NEXT: br label [[END:%.*]] +; CHECK: else: +; CHECK-NEXT: store atomic i32 0, ptr [[P]] seq_cst, align 4 +; CHECK-NEXT: br label [[END]] +; CHECK: end: +; CHECK-NEXT: ret void ; br i1 %c, label %if, label %else @@ -93,8 +131,9 @@ end: ; Calls a function that is not guaranteed to return, not willreturn. define void @willreturn_non_returning_function(i1 %c, ptr %p) { -; CHECK-NOT: Function Attrs: {{.*}}willreturn -; CHECK: define void @willreturn_non_returning_function( +; CHECK-LABEL: @willreturn_non_returning_function( +; CHECK-NEXT: call void @unknown_fn() +; CHECK-NEXT: ret void ; call void @unknown_fn() ret void @@ -102,8 +141,11 @@ define void @willreturn_non_returning_function(i1 %c, ptr %p) { ; Infinite loop without mustprogress, will not return. define void @willreturn_loop() { -; CHECK-NOT: Function Attrs: {{.*}}willreturn -; CHECK: define void @willreturn_loop( +; CHECK: Function Attrs: nofree norecurse noreturn nosync nounwind readnone +; CHECK-LABEL: @willreturn_loop( +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: br label [[LOOP]] ; br label %loop @@ -114,8 +156,17 @@ loop: ; Finite loop. Could be willreturn but not detected. ; FIXME define void @willreturn_finite_loop() { -; CHECK-NOT: Function Attrs: {{.*}}willreturn -; CHECK: define void @willreturn_finite_loop( +; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone +; CHECK-LABEL: @willreturn_finite_loop( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_INC:%.*]], [[LOOP]] ] +; CHECK-NEXT: [[I_INC]] = add nuw i32 [[I]], 1 +; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I_INC]], 100 +; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[END:%.*]] +; CHECK: end: +; CHECK-NEXT: ret void ; entry: br label %loop @@ -132,8 +183,10 @@ end: ; Infinite recursion without mustprogress, will not return. define void @willreturn_recursion() { -; CHECK-NOT: Function Attrs: {{.*}}willreturn -; CHECK: define void @willreturn_recursion( +; CHECK: Function Attrs: nofree nosync nounwind readnone +; CHECK-LABEL: @willreturn_recursion( +; CHECK-NEXT: tail call void @willreturn_recursion() +; CHECK-NEXT: ret void ; tail call void @willreturn_recursion() ret void @@ -141,8 +194,13 @@ define void @willreturn_recursion() { ; Irreducible infinite loop, will not return. define void @willreturn_irreducible(i1 %c) { -; CHECK-NOT: Function Attrs: {{.*}}willreturn -; CHECK: define void @willreturn_irreducible( +; CHECK: Function Attrs: nofree norecurse noreturn nosync nounwind readnone +; CHECK-LABEL: @willreturn_irreducible( +; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] +; CHECK: bb1: +; CHECK-NEXT: br label [[BB2]] +; CHECK: bb2: +; CHECK-NEXT: br label [[BB1]] ; br i1 %c, label %bb1, label %bb2 @@ -154,10 +212,12 @@ bb2: } define linkonce i32 @square(i32) { -; CHECK-NOT: Function Attrs: {{.*}}willreturn -; CHECK: define linkonce i32 @square( - %2 = mul nsw i32 %0, %0 - ret i32 %2 +; CHECK-LABEL: @square( +; CHECK-NEXT: [[TMP2:%.*]] = mul nsw i32 [[TMP0:%.*]], [[TMP0]] +; CHECK-NEXT: ret i32 [[TMP2]] +; + %2 = mul nsw i32 %0, %0 + ret i32 %2 } declare i64 @fn_noread() readnone diff --git a/llvm/test/Transforms/FunctionAttrs/writeonly.ll b/llvm/test/Transforms/FunctionAttrs/writeonly.ll index ea90077..7828d2f 100644 --- a/llvm/test/Transforms/FunctionAttrs/writeonly.ll +++ b/llvm/test/Transforms/FunctionAttrs/writeonly.ll @@ -1,14 +1,25 @@ -; RUN: opt < %s -function-attrs -S | FileCheck %s +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes ; RUN: opt < %s -passes=function-attrs -S | FileCheck %s -; CHECK: define void @nouses-argworn-funrn(ptr nocapture readnone %.aaa) #0 { define void @nouses-argworn-funrn(ptr writeonly %.aaa) { +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn +; CHECK-LABEL: define {{[^@]+}}@nouses-argworn-funrn +; CHECK-SAME: (ptr nocapture readnone [[DOTAAA:%.*]]) #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: nouses-argworn-funrn_entry: +; CHECK-NEXT: ret void +; nouses-argworn-funrn_entry: ret void } -; CHECK: define void @nouses-argworn-funro(ptr nocapture readnone %.aaa, ptr nocapture readonly %.bbb) #1 { define void @nouses-argworn-funro(ptr writeonly %.aaa, ptr %.bbb) { +; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind readonly willreturn +; CHECK-LABEL: define {{[^@]+}}@nouses-argworn-funro +; CHECK-SAME: (ptr nocapture readnone [[DOTAAA:%.*]], ptr nocapture readonly [[DOTBBB:%.*]]) #[[ATTR1:[0-9]+]] { +; CHECK-NEXT: nouses-argworn-funro_entry: +; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr [[DOTBBB]], align 4 +; CHECK-NEXT: ret void +; nouses-argworn-funro_entry: %val = load i32 , ptr %.bbb ret void @@ -18,50 +29,90 @@ nouses-argworn-funro_entry: @d-ccc = internal global %_type_of_d-ccc <{ ptr null, i8 1, i8 13, i8 0, i8 -127 }>, align 8 -; CHECK: define void @nouses-argworn-funwo(ptr nocapture readnone %.aaa) #2 { define void @nouses-argworn-funwo(ptr writeonly %.aaa) { +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn writeonly +; CHECK-LABEL: define {{[^@]+}}@nouses-argworn-funwo +; CHECK-SAME: (ptr nocapture readnone [[DOTAAA:%.*]]) #[[ATTR2:[0-9]+]] { +; CHECK-NEXT: nouses-argworn-funwo_entry: +; CHECK-NEXT: store i8 0, ptr getelementptr inbounds ([[_TYPE_OF_D_CCC:%.*]], ptr @d-ccc, i32 0, i32 3), align 1 +; CHECK-NEXT: ret void +; nouses-argworn-funwo_entry: store i8 0, ptr getelementptr inbounds (%_type_of_d-ccc, ptr @d-ccc, i32 0, i32 3) ret void } -; CHECK: define void @test_store(ptr nocapture writeonly %p) define void @test_store(ptr %p) { +; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind willreturn writeonly +; CHECK-LABEL: define {{[^@]+}}@test_store +; CHECK-SAME: (ptr nocapture writeonly [[P:%.*]]) #[[ATTR3:[0-9]+]] { +; CHECK-NEXT: store i8 0, ptr [[P]], align 1 +; CHECK-NEXT: ret void +; store i8 0, ptr %p ret void } @G = external global ptr -; CHECK: define i8 @test_store_capture(ptr %p) define i8 @test_store_capture(ptr %p) { +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn +; CHECK-LABEL: define {{[^@]+}}@test_store_capture +; CHECK-SAME: (ptr [[P:%.*]]) #[[ATTR4:[0-9]+]] { +; CHECK-NEXT: store ptr [[P]], ptr @G, align 8 +; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr @G, align 8 +; CHECK-NEXT: [[V:%.*]] = load i8, ptr [[P2]], align 1 +; CHECK-NEXT: ret i8 [[V]] +; store ptr %p, ptr @G %p2 = load ptr, ptr @G %v = load i8, ptr %p2 ret i8 %v } -; CHECK: define void @test_addressing(ptr nocapture writeonly %p) define void @test_addressing(ptr %p) { +; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind willreturn writeonly +; CHECK-LABEL: define {{[^@]+}}@test_addressing +; CHECK-SAME: (ptr nocapture writeonly [[P:%.*]]) #[[ATTR3]] { +; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[P]], i64 8 +; CHECK-NEXT: store i32 0, ptr [[GEP]], align 4 +; CHECK-NEXT: ret void +; %gep = getelementptr i8, ptr %p, i64 8 store i32 0, ptr %gep ret void } -; CHECK: define void @test_readwrite(ptr nocapture %p) define void @test_readwrite(ptr %p) { +; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nosync nounwind willreturn +; CHECK-LABEL: define {{[^@]+}}@test_readwrite +; CHECK-SAME: (ptr nocapture [[P:%.*]]) #[[ATTR5:[0-9]+]] { +; CHECK-NEXT: [[V:%.*]] = load i8, ptr [[P]], align 1 +; CHECK-NEXT: store i8 [[V]], ptr [[P]], align 1 +; CHECK-NEXT: ret void +; %v = load i8, ptr %p store i8 %v, ptr %p ret void } -; CHECK: define void @test_volatile(ptr %p) define void @test_volatile(ptr %p) { +; CHECK: Function Attrs: argmemonly nofree norecurse nounwind +; CHECK-LABEL: define {{[^@]+}}@test_volatile +; CHECK-SAME: (ptr [[P:%.*]]) #[[ATTR6:[0-9]+]] { +; CHECK-NEXT: store volatile i8 0, ptr [[P]], align 1 +; CHECK-NEXT: ret void +; store volatile i8 0, ptr %p ret void } -; CHECK: define void @test_atomicrmw(ptr nocapture %p) define void @test_atomicrmw(ptr %p) { +; CHECK: Function Attrs: argmemonly mustprogress nofree norecurse nounwind willreturn +; CHECK-LABEL: define {{[^@]+}}@test_atomicrmw +; CHECK-SAME: (ptr nocapture [[P:%.*]]) #[[ATTR7:[0-9]+]] { +; CHECK-NEXT: [[TMP1:%.*]] = atomicrmw add ptr [[P]], i8 0 seq_cst, align 1 +; CHECK-NEXT: ret void +; atomicrmw add ptr %p, i8 0 seq_cst ret void } @@ -69,8 +120,12 @@ define void @test_atomicrmw(ptr %p) { declare void @direct1_callee(ptr %p) -; CHECK: define void @direct1(ptr %p) define void @direct1(ptr %p) { +; CHECK-LABEL: define {{[^@]+}}@direct1 +; CHECK-SAME: (ptr [[P:%.*]]) { +; CHECK-NEXT: call void @direct1_callee(ptr [[P]]) +; CHECK-NEXT: ret void +; call void @direct1_callee(ptr %p) ret void } @@ -78,51 +133,78 @@ define void @direct1(ptr %p) { declare void @direct2_callee(ptr %p) writeonly ; writeonly w/o nocapture is not enough -; CHECK: define void @direct2(ptr %p) define void @direct2(ptr %p) { +; CHECK: Function Attrs: writeonly +; CHECK-LABEL: define {{[^@]+}}@direct2 +; CHECK-SAME: (ptr [[P:%.*]]) #[[ATTR8:[0-9]+]] { +; CHECK-NEXT: call void @direct2_callee(ptr [[P]]) +; CHECK-NEXT: ret void +; call void @direct2_callee(ptr %p) ; read back from global, read through pointer... ret void } -; CHECK: define void @direct2b(ptr nocapture writeonly %p) define void @direct2b(ptr %p) { +; CHECK: Function Attrs: writeonly +; CHECK-LABEL: define {{[^@]+}}@direct2b +; CHECK-SAME: (ptr nocapture writeonly [[P:%.*]]) #[[ATTR8]] { +; CHECK-NEXT: call void @direct2_callee(ptr nocapture [[P]]) +; CHECK-NEXT: ret void +; call void @direct2_callee(ptr nocapture %p) ret void } declare void @direct3_callee(ptr nocapture writeonly %p) -; CHECK: define void @direct3(ptr nocapture writeonly %p) define void @direct3(ptr %p) { +; CHECK-LABEL: define {{[^@]+}}@direct3 +; CHECK-SAME: (ptr nocapture writeonly [[P:%.*]]) { +; CHECK-NEXT: call void @direct3_callee(ptr [[P]]) +; CHECK-NEXT: ret void +; call void @direct3_callee(ptr %p) ret void } -; CHECK: define void @direct3b(ptr %p) define void @direct3b(ptr %p) { +; CHECK-LABEL: define {{[^@]+}}@direct3b +; CHECK-SAME: (ptr [[P:%.*]]) { +; CHECK-NEXT: call void @direct3_callee(ptr [[P]]) [ "may-read-and-capture"(ptr [[P]]) ] +; CHECK-NEXT: ret void +; call void @direct3_callee(ptr %p) ["may-read-and-capture"(ptr %p)] ret void } -; CHECK: define void @fptr_test1(ptr %p, ptr nocapture readonly %f) define void @fptr_test1(ptr %p, ptr %f) { +; CHECK-LABEL: define {{[^@]+}}@fptr_test1 +; CHECK-SAME: (ptr [[P:%.*]], ptr nocapture readonly [[F:%.*]]) { +; CHECK-NEXT: call void [[F]](ptr [[P]]) +; CHECK-NEXT: ret void +; call void %f(ptr %p) ret void } -; CHECK: define void @fptr_test2(ptr nocapture writeonly %p, ptr nocapture readonly %f) define void @fptr_test2(ptr %p, ptr %f) { +; CHECK-LABEL: define {{[^@]+}}@fptr_test2 +; CHECK-SAME: (ptr nocapture writeonly [[P:%.*]], ptr nocapture readonly [[F:%.*]]) { +; CHECK-NEXT: call void [[F]](ptr nocapture writeonly [[P]]) +; CHECK-NEXT: ret void +; call void %f(ptr nocapture writeonly %p) ret void } -; CHECK: define void @fptr_test3(ptr nocapture writeonly %p, ptr nocapture readonly %f) define void @fptr_test3(ptr %p, ptr %f) { +; CHECK: Function Attrs: writeonly +; CHECK-LABEL: define {{[^@]+}}@fptr_test3 +; CHECK-SAME: (ptr nocapture writeonly [[P:%.*]], ptr nocapture readonly [[F:%.*]]) #[[ATTR8]] { +; CHECK-NEXT: call void [[F]](ptr nocapture [[P]]) #[[ATTR8]] +; CHECK-NEXT: ret void +; call void %f(ptr nocapture %p) writeonly ret void } - -; CHECK: attributes #0 = { {{.*}}readnone{{.*}} } -; CHECK: attributes #1 = { {{.*}}readonly{{.*}} } -; CHECK: attributes #2 = { {{.*}}writeonly{{.*}} } -- 2.7.4