1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-globals 2; RUN: opt -S -mtriple=amdgcn-amd- -amdgpu-annotate-kernel-features %s | FileCheck --allow-unused-prefixes -check-prefixes=CHECK,AKF_CHECK %s 3; RUN: opt -S -mtriple=amdgcn-amd- -amdgpu-attributor %s | FileCheck --allow-unused-prefixes -check-prefixes=CHECK,ATTRIBUTOR_CHECK %s 4 5; Test to ensure recursive functions exhibit proper behaviour 6; Test to generate fibonacci numbers 7 8define i32 @fib(i32 %n) #0 { 9; CHECK-LABEL: define {{[^@]+}}@fib 10; CHECK-SAME: (i32 [[N:%.*]]) #[[ATTR0:[0-9]+]] { 11; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[N]], 0 12; CHECK-NEXT: br i1 [[CMP1]], label [[EXIT:%.*]], label [[CONT1:%.*]] 13; CHECK: cont1: 14; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[N]], 1 15; CHECK-NEXT: br i1 [[CMP2]], label [[EXIT]], label [[CONT2:%.*]] 16; CHECK: cont2: 17; CHECK-NEXT: [[NM1:%.*]] = sub i32 [[N]], 1 18; CHECK-NEXT: [[FIBM1:%.*]] = call i32 @fib(i32 [[NM1]]) 19; CHECK-NEXT: [[NM2:%.*]] = sub i32 [[N]], 2 20; CHECK-NEXT: [[FIBM2:%.*]] = call i32 @fib(i32 [[NM2]]) 21; CHECK-NEXT: [[RETVAL:%.*]] = add i32 [[FIBM1]], [[FIBM2]] 22; CHECK-NEXT: ret i32 [[RETVAL]] 23; CHECK: exit: 24; CHECK-NEXT: ret i32 1 25; 26 %cmp1 = icmp eq i32 %n, 0 27 br i1 %cmp1, label %exit, label %cont1 28 29cont1: 30 %cmp2 = icmp eq i32 %n, 1 31 br i1 %cmp2, label %exit, label %cont2 32 33cont2: 34 %nm1 = sub i32 %n, 1 35 %fibm1 = call i32 @fib(i32 %nm1) 36 %nm2 = sub i32 %n, 2 37 %fibm2 = call i32 @fib(i32 %nm2) 38 %retval = add i32 %fibm1, %fibm2 39 40 ret i32 %retval 41 42exit: 43 ret i32 1 44} 45 46define internal i32 @fib_internal(i32 %n) #0 { 47; AKF_CHECK-LABEL: define {{[^@]+}}@fib_internal 48; AKF_CHECK-SAME: (i32 [[N:%.*]]) #[[ATTR0]] { 49; AKF_CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[N]], 0 50; AKF_CHECK-NEXT: br i1 [[CMP1]], label [[EXIT:%.*]], label [[CONT1:%.*]] 51; AKF_CHECK: cont1: 52; AKF_CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[N]], 1 53; AKF_CHECK-NEXT: br i1 [[CMP2]], label [[EXIT]], label [[CONT2:%.*]] 54; AKF_CHECK: cont2: 55; AKF_CHECK-NEXT: [[NM1:%.*]] = sub i32 [[N]], 1 56; AKF_CHECK-NEXT: [[FIBM1:%.*]] = call i32 @fib_internal(i32 [[NM1]]) 57; AKF_CHECK-NEXT: [[NM2:%.*]] = sub i32 [[N]], 2 58; AKF_CHECK-NEXT: [[FIBM2:%.*]] = call i32 @fib_internal(i32 [[NM2]]) 59; AKF_CHECK-NEXT: [[RETVAL:%.*]] = add i32 [[FIBM1]], [[FIBM2]] 60; AKF_CHECK-NEXT: ret i32 [[RETVAL]] 61; AKF_CHECK: exit: 62; AKF_CHECK-NEXT: ret i32 1 63; 64; ATTRIBUTOR_CHECK-LABEL: define {{[^@]+}}@fib_internal 65; ATTRIBUTOR_CHECK-SAME: (i32 [[N:%.*]]) #[[ATTR1:[0-9]+]] { 66; ATTRIBUTOR_CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[N]], 0 67; ATTRIBUTOR_CHECK-NEXT: br i1 [[CMP1]], label [[EXIT:%.*]], label [[CONT1:%.*]] 68; ATTRIBUTOR_CHECK: cont1: 69; ATTRIBUTOR_CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[N]], 1 70; ATTRIBUTOR_CHECK-NEXT: br i1 [[CMP2]], label [[EXIT]], label [[CONT2:%.*]] 71; ATTRIBUTOR_CHECK: cont2: 72; ATTRIBUTOR_CHECK-NEXT: [[NM1:%.*]] = sub i32 [[N]], 1 73; ATTRIBUTOR_CHECK-NEXT: [[FIBM1:%.*]] = call i32 @fib_internal(i32 [[NM1]]) 74; ATTRIBUTOR_CHECK-NEXT: [[NM2:%.*]] = sub i32 [[N]], 2 75; ATTRIBUTOR_CHECK-NEXT: [[FIBM2:%.*]] = call i32 @fib_internal(i32 [[NM2]]) 76; ATTRIBUTOR_CHECK-NEXT: [[RETVAL:%.*]] = add i32 [[FIBM1]], [[FIBM2]] 77; ATTRIBUTOR_CHECK-NEXT: ret i32 [[RETVAL]] 78; ATTRIBUTOR_CHECK: exit: 79; ATTRIBUTOR_CHECK-NEXT: ret i32 1 80; 81 %cmp1 = icmp eq i32 %n, 0 82 br i1 %cmp1, label %exit, label %cont1 83 84cont1: 85 %cmp2 = icmp eq i32 %n, 1 86 br i1 %cmp2, label %exit, label %cont2 87 88cont2: 89 %nm1 = sub i32 %n, 1 90 %fibm1 = call i32 @fib_internal(i32 %nm1) 91 %nm2 = sub i32 %n, 2 92 %fibm2 = call i32 @fib_internal(i32 %nm2) 93 %retval = add i32 %fibm1, %fibm2 94 95 ret i32 %retval 96 97exit: 98 ret i32 1 99} 100 101define amdgpu_kernel void @kernel(i32 addrspace(1)* %m) #1 { 102; AKF_CHECK-LABEL: define {{[^@]+}}@kernel 103; AKF_CHECK-SAME: (i32 addrspace(1)* [[M:%.*]]) #[[ATTR1:[0-9]+]] { 104; AKF_CHECK-NEXT: [[R:%.*]] = call i32 @fib(i32 5) 105; AKF_CHECK-NEXT: [[R2:%.*]] = call i32 @fib_internal(i32 5) 106; AKF_CHECK-NEXT: store i32 [[R]], i32 addrspace(1)* [[M]], align 4 107; AKF_CHECK-NEXT: store i32 [[R2]], i32 addrspace(1)* [[M]], align 4 108; AKF_CHECK-NEXT: ret void 109; 110; ATTRIBUTOR_CHECK-LABEL: define {{[^@]+}}@kernel 111; ATTRIBUTOR_CHECK-SAME: (i32 addrspace(1)* [[M:%.*]]) #[[ATTR2:[0-9]+]] { 112; ATTRIBUTOR_CHECK-NEXT: [[R:%.*]] = call i32 @fib(i32 5) 113; ATTRIBUTOR_CHECK-NEXT: [[R2:%.*]] = call i32 @fib_internal(i32 5) 114; ATTRIBUTOR_CHECK-NEXT: store i32 [[R]], i32 addrspace(1)* [[M]], align 4 115; ATTRIBUTOR_CHECK-NEXT: store i32 [[R2]], i32 addrspace(1)* [[M]], align 4 116; ATTRIBUTOR_CHECK-NEXT: ret void 117; 118 %r = call i32 @fib(i32 5) 119 %r2 = call i32 @fib_internal(i32 5) 120 121 store i32 %r, i32 addrspace(1)* %m 122 store i32 %r2, i32 addrspace(1)* %m 123 ret void 124} 125 126; nounwind and readnone are added to match attributor results. 127attributes #0 = { nounwind readnone } 128attributes #1 = { "uniform-work-group-size"="true" } 129 130;. 131; AKF_CHECK: attributes #[[ATTR0]] = { nounwind readnone "uniform-work-group-size"="true" } 132; AKF_CHECK: attributes #[[ATTR1]] = { "amdgpu-calls" "uniform-work-group-size"="true" } 133;. 134; ATTRIBUTOR_CHECK: attributes #[[ATTR0]] = { nounwind readnone "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="false" } 135; ATTRIBUTOR_CHECK: attributes #[[ATTR1]] = { nounwind readnone "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="true" } 136; ATTRIBUTOR_CHECK: attributes #[[ATTR2]] = { "amdgpu-no-dispatch-id" "amdgpu-no-dispatch-ptr" "amdgpu-no-implicitarg-ptr" "amdgpu-no-queue-ptr" "amdgpu-no-workgroup-id-x" "amdgpu-no-workgroup-id-y" "amdgpu-no-workgroup-id-z" "amdgpu-no-workitem-id-x" "amdgpu-no-workitem-id-y" "amdgpu-no-workitem-id-z" "uniform-work-group-size"="true" } 137;. 138