1// RUN: %clang_cc1 -x hlsl -triple dxil-pc-shadermodel6.3-library -finclude-default-header %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s 2// RUN: %clang_cc1 -x hlsl -triple dxil-pc-shadermodel6.0-compute -finclude-default-header %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s 3 4// Verify that a few different function types all get the NoRecurse attribute 5 6#define MAX 100 7 8struct Node { 9 uint value; 10 uint key; 11 uint left, right; 12}; 13 14// CHECK: Function Attrs:{{.*}}norecurse 15// CHECK: define noundef i32 @_Z4FindA100_4Nodej(ptr noundef byval([100 x %struct.Node]) align 4 %SortedTree, i32 noundef %key) [[IntAttr:\#[0-9]+]] 16// CHECK: ret i32 17// Find and return value corresponding to key in the SortedTree 18uint Find(Node SortedTree[MAX], uint key) { 19 uint nix = 0; // head 20 while(true) { 21 if (nix < 0) 22 return 0.0; // Not found 23 Node n = SortedTree[nix]; 24 if (n.key == key) 25 return n.value; 26 if (key < n.key) 27 nix = n.left; 28 else 29 nix = n.right; 30 } 31} 32 33// CHECK: Function Attrs:{{.*}}norecurse 34// CHECK: define noundef i1 @_Z8InitTreeA100_4NodeN4hlsl8RWBufferIDv4_jEEj(ptr noundef byval([100 x %struct.Node]) align 4 %tree, ptr noundef byval(%"class.hlsl::RWBuffer") align 4 %encodedTree, i32 noundef %maxDepth) [[ExtAttr:\#[0-9]+]] 35// CHECK: ret i1 36// Initialize tree with given buffer 37// Imagine the inout works 38export 39bool InitTree(/*inout*/ Node tree[MAX], RWBuffer<uint4> encodedTree, uint maxDepth) { 40 uint size = pow(2.f, (float)maxDepth) - 1; 41 if (size > MAX) return false; 42 for (uint i = 1; i < size; i++) { 43 tree[i].value = encodedTree[i].x; 44 tree[i].key = encodedTree[i].y; 45 tree[i].left = encodedTree[i].z; 46 tree[i].right = encodedTree[i].w; 47 } 48 return true; 49} 50 51RWBuffer<uint4> gTree; 52 53// Mangled entry points are internal 54// CHECK: Function Attrs:{{.*}}norecurse 55// CHECK: define internal void @_Z4mainj(i32 noundef %GI) [[IntAttr]] 56// CHECK: ret void 57 58// Canonical entry points are external and shader attributed 59// CHECK: Function Attrs:{{.*}}norecurse 60// CHECK: define void @main() [[EntryAttr:\#[0-9]+]] 61// CHECK: ret void 62 63[numthreads(1,1,1)] 64[shader("compute")] 65void main(uint GI : SV_GroupIndex) { 66 Node haystack[MAX]; 67 uint needle = 0; 68 if (InitTree(haystack, gTree, GI)) 69 needle = Find(haystack, needle); 70} 71 72// Mangled entry points are internal 73// CHECK: Function Attrs:{{.*}}norecurse 74// CHECK: define internal void @_Z11defaultMainv() [[IntAttr]] 75// CHECK: ret void 76 77// Canonical entry points are external and shader attributed 78// CHECK: Function Attrs:{{.*}}norecurse 79// CHECK: define void @defaultMain() [[EntryAttr]] 80// CHECK: ret void 81 82[numthreads(1,1,1)] 83[shader("compute")] 84void defaultMain() { 85 Node haystack[MAX]; 86 uint needle = 0; 87 if (InitTree(haystack, gTree, 4)) 88 needle = Find(haystack, needle); 89} 90 91// CHECK: attributes [[IntAttr]] = {{.*}} norecurse 92// CHECK: attributes [[ExtAttr]] = {{.*}} norecurse 93// CHECK: attributes [[EntryAttr]] = {{.*}} norecurse 94