89 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --check-globals all --version 52; RUN: opt < %s -passes=norecurse-lto-inference -S | FileCheck %s3 4; This test includes a call graph with a self recursive function.5; The purpose of this is to check that norecurse is added to functions6; which have a self-recursive function in the call-chain.7; The call-chain in this test is as follows8; main -> bob -> callee1 -> callee29; where callee2 is self recursive.10 11@x = dso_local global i32 4, align 412@y = dso_local global i32 2, align 413 14;.15; CHECK: @x = dso_local global i32 4, align 416; CHECK: @y = dso_local global i32 2, align 417;.18define internal void @callee2() {19; CHECK: Function Attrs: norecurse20; CHECK-LABEL: define internal void @callee2(21; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {22; CHECK-NEXT: [[ENTRY:.*:]]23; CHECK-NEXT: [[TMP0:%.*]] = load volatile i32, ptr @y, align 424; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP0]], 125; CHECK-NEXT: store volatile i32 [[INC]], ptr @y, align 426; CHECK-NEXT: ret void27;28entry:29 %0 = load volatile i32, ptr @y, align 430 %inc = add nsw i32 %0, 131 store volatile i32 %inc, ptr @y, align 432 ret void33}34 35define internal void @callee1(i32 %x) {36; CHECK-LABEL: define internal void @callee1(37; CHECK-SAME: i32 [[X:%.*]]) {38; CHECK-NEXT: [[ENTRY:.*:]]39; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X]], 040; CHECK-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]41; CHECK: [[IF_THEN]]:42; CHECK-NEXT: tail call void @callee1(i32 [[X]])43; CHECK-NEXT: br label %[[IF_END]]44; CHECK: [[IF_END]]:45; CHECK-NEXT: tail call void @callee2()46; CHECK-NEXT: ret void47;48entry:49 %cmp = icmp sgt i32 %x, 050 br i1 %cmp, label %if.then, label %if.end51 52if.then: ; preds = %entry53 tail call void @callee1(i32 %x)54 br label %if.end55 56if.end: ; preds = %if.then, %entry57 tail call void @callee2()58 ret void59}60 61define internal void @bob() {62; CHECK-LABEL: define internal void @bob() {63; CHECK-NEXT: [[ENTRY:.*:]]64; CHECK-NEXT: [[TMP0:%.*]] = load volatile i32, ptr @x, align 465; CHECK-NEXT: tail call void @callee2(i32 [[TMP0]])66; CHECK-NEXT: ret void67;68entry:69 %0 = load volatile i32, ptr @x, align 470 tail call void @callee2(i32 %0)71 ret void72}73 74define dso_local i32 @main() norecurse {75; CHECK: Function Attrs: norecurse76; CHECK-LABEL: define dso_local i32 @main(77; CHECK-SAME: ) #[[ATTR0]] {78; CHECK-NEXT: [[ENTRY:.*:]]79; CHECK-NEXT: tail call void @bob()80; CHECK-NEXT: ret i32 081;82entry:83 tail call void @bob()84 ret i32 085}86;.87; CHECK: attributes #[[ATTR0]] = { norecurse }88;.89