; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -inline -S -enable-new-pm=0 %s | FileCheck %s ; readnone but may not return according to attributes. define void @readnone_may_not_return() nounwind readnone ssp { ; CHECK-LABEL: @readnone_may_not_return( ; CHECK-NEXT: entry: ; CHECK-NEXT: br label [[WHILE_BODY:%.*]] ; CHECK: while.body: ; CHECK-NEXT: br label [[WHILE_BODY]] ; entry: br label %while.body while.body: br label %while.body } ; readnone and guaranteed to return according to attributes. define void @readnone_willreturn() willreturn nounwind readnone ssp { ; CHECK-LABEL: @readnone_willreturn( ; CHECK-NEXT: entry: ; CHECK-NEXT: ret void ; entry: ret void } ; Make sure the call to @readnone is not treated as dead, because it is not ; marked as willreturn. define void @caller_may_not_return() ssp { ; CHECK-LABEL: @caller_may_not_return( ; CHECK-NEXT: entry: ; CHECK-NEXT: br label [[WHILE_BODY_I:%.*]] ; CHECK: while.body.i: ; CHECK-NEXT: br label [[WHILE_BODY_I]] ; CHECK: readnone_may_not_return.exit: ; CHECK-NEXT: ret void ; entry: call void @readnone_may_not_return() call void @readnone_willreturn() ret void } ; @caller_willreturn is marked as willreturn, so all called functions also must ; return. All calls are dead. define void @caller_willreturn() ssp { ; CHECK-LABEL: @caller_willreturn( ; CHECK-NEXT: entry: ; CHECK-NEXT: ret void ; entry: call void @readnone_may_not_return() willreturn call void @readnone_willreturn() ret void }