1// RUN: %clang_cc1 -triple spir-unknown-unknown -emit-llvm %s -o - | opt -instnamer -S | FileCheck %s 2 3void convfun(void) __attribute__((convergent)); 4void non_convfun(void); 5void nodupfun(void) __attribute__((noduplicate)); 6 7void f(void); 8void g(void); 9 10// Test two if's are merged and non_convfun duplicated. 11// The LLVM IR is equivalent to: 12// if (a) { 13// f(); 14// non_convfun(); 15// g(); 16// } else { 17// non_convfun(); 18// } 19// 20// CHECK: define spir_func void @test_merge_if(i32 %[[a:.+]]) 21// CHECK: %[[tobool:.+]] = icmp eq i32 %[[a]], 0 22// CHECK: br i1 %[[tobool]], label %[[if_end3_critedge:.+]], label %[[if_then:.+]] 23// CHECK: [[if_then]]: 24// CHECK: tail call spir_func void @f() 25// CHECK: tail call spir_func void @non_convfun() 26// CHECK: tail call spir_func void @g() 27// CHECK: br label %[[if_end3:.+]] 28// CHECK: [[if_end3_critedge]]: 29// CHECK: tail call spir_func void @non_convfun() 30// CHECK: br label %[[if_end3]] 31// CHECK: [[if_end3]]: 32// CHECK-LABEL: ret void 33 34void test_merge_if(int a) { 35 if (a) { 36 f(); 37 } 38 non_convfun(); 39 if (a) { 40 g(); 41 } 42} 43 44// CHECK-DAG: declare spir_func void @f() 45// CHECK-DAG: declare spir_func void @non_convfun() 46// CHECK-DAG: declare spir_func void @g() 47 48// Test two if's are not merged. 49// CHECK: define spir_func void @test_no_merge_if(i32 %[[a:.+]]) 50// CHECK: %[[tobool:.+]] = icmp eq i32 %[[a]], 0 51// CHECK: br i1 %[[tobool]], label %[[if_end:.+]], label %[[if_then:.+]] 52// CHECK: [[if_then]]: 53// CHECK: tail call spir_func void @f() 54// CHECK-NOT: call spir_func void @convfun() 55// CHECK-NOT: call spir_func void @g() 56// CHECK: br label %[[if_end]] 57// CHECK: [[if_end]]: 58// CHECK: %[[tobool_pr:.+]] = phi i1 [ true, %[[if_then]] ], [ false, %{{.+}} ] 59// CHECK: tail call spir_func void @convfun() #[[attr5:.+]] 60// CHECK: br i1 %[[tobool_pr]], label %[[if_then2:.+]], label %[[if_end3:.+]] 61// CHECK: [[if_then2]]: 62// CHECK: tail call spir_func void @g() 63// CHECK: br label %[[if_end3:.+]] 64// CHECK: [[if_end3]]: 65// CHECK-LABEL: ret void 66 67void test_no_merge_if(int a) { 68 if (a) { 69 f(); 70 } 71 convfun(); 72 if(a) { 73 g(); 74 } 75} 76 77// CHECK: declare spir_func void @convfun(){{[^#]*}} #[[attr2:[0-9]+]] 78 79// Test loop is unrolled for convergent function. 80// CHECK-LABEL: define spir_func void @test_unroll() 81// CHECK: tail call spir_func void @convfun() #[[attr5:[0-9]+]] 82// CHECK: tail call spir_func void @convfun() #[[attr5]] 83// CHECK: tail call spir_func void @convfun() #[[attr5]] 84// CHECK: tail call spir_func void @convfun() #[[attr5]] 85// CHECK: tail call spir_func void @convfun() #[[attr5]] 86// CHECK: tail call spir_func void @convfun() #[[attr5]] 87// CHECK: tail call spir_func void @convfun() #[[attr5]] 88// CHECK: tail call spir_func void @convfun() #[[attr5]] 89// CHECK: tail call spir_func void @convfun() #[[attr5]] 90// CHECK: tail call spir_func void @convfun() #[[attr5]] 91// CHECK-LABEL: ret void 92 93void test_unroll() { 94 for (int i = 0; i < 10; i++) 95 convfun(); 96} 97 98// Test loop is not unrolled for noduplicate function. 99// CHECK-LABEL: define spir_func void @test_not_unroll() 100// CHECK: br label %[[for_body:.+]] 101// CHECK: [[for_cond_cleanup:.+]]: 102// CHECK: ret void 103// CHECK: [[for_body]]: 104// CHECK: tail call spir_func void @nodupfun() #[[attr6:[0-9]+]] 105// CHECK-NOT: call spir_func void @nodupfun() 106// CHECK: br i1 %{{.+}}, label %[[for_body]], label %[[for_cond_cleanup]] 107 108void test_not_unroll() { 109 for (int i = 0; i < 10; i++) 110 nodupfun(); 111} 112 113// CHECK: declare spir_func void @nodupfun(){{[^#]*}} #[[attr3:[0-9]+]] 114 115// CHECK-DAG: attributes #[[attr2]] = { {{[^}]*}}convergent{{[^}]*}} } 116// CHECK-DAG: attributes #[[attr3]] = { {{[^}]*}}noduplicate{{[^}]*}} } 117// CHECK-DAG: attributes #[[attr5]] = { {{[^}]*}}convergent{{[^}]*}} } 118// CHECK-DAG: attributes #[[attr6]] = { {{[^}]*}}noduplicate{{[^}]*}} } 119