// RUN: %clang_cc1 -triple spir-unknown-unknown -emit-llvm %s -o - | opt -instnamer -S | FileCheck -enable-var-scope %s
// This is initially assumed convergent, but can be deduced to not require it.
// CHECK-LABEL: define{{.*}} spir_func void @non_convfun;
*p = 0;
}
void convfun __attribute__;
void nodupfun __attribute__;
// External functions should be assumed convergent.
void f;
void g;
// Test two if's are merged and non_convfun duplicated.
// The LLVM IR is equivalent to:
// if {
// f;
// non_convfun;
// g;
// } else {
// non_convfun;
// }
//
// CHECK-LABEL: define{{.*}} spir_func void @test_merge_if local_unnamed_addr #1 {
// CHECK: %[[tobool:.+]] = icmp eq i32 %a, 0
// CHECK: br i1 %[[tobool]], label %[[if_end3_critedge:.+]], label %[[if_then:.+]]
// CHECK: [[if_then]]:
// CHECK: tail call spir_func void @f
// CHECK: tail call spir_func void @non_convfun
// CHECK: tail call spir_func void @g
// CHECK: br label %[[if_end3:.+]]
// CHECK: [[if_end3_critedge]]:
// CHECK: tail call spir_func void @non_convfun
// CHECK: br label %[[if_end3]]
// CHECK: [[if_end3]]:
// CHECK: ret void
void test_merge_if {
if {
f;
}
non_convfun;
if {
g;
}
}
// CHECK-DAG: declare spir_func void @f local_unnamed_addr #2
// CHECK-DAG: declare spir_func void @g local_unnamed_addr #2
// Test two if's are not merged.
// CHECK-LABEL: define{{.*}} spir_func void @test_no_merge_if local_unnamed_addr #1
// CHECK: %[[tobool:.+]] = icmp eq i32 %a, 0
// CHECK: br i1 %[[tobool]], label %[[if_end:.+]], label %[[if_then:.+]]
// CHECK: [[if_then]]:
// CHECK: tail call spir_func void @f
// CHECK-NOT: call spir_func void @convfun
// CHECK-NOT: call spir_func void @g
// CHECK: br label %[[if_end]]
// CHECK: [[if_end]]:
// CHECK-NOT: phi i1
// CHECK: tail call spir_func void @convfun #[[attr4:.+]]
// CHECK: br i1 %[[tobool]], label %[[if_end3:.+]], label %[[if_then2:.+]]
// CHECK: [[if_then2]]:
// CHECK: tail call spir_func void @g
// CHECK: br label %[[if_end3:.+]]
// CHECK: [[if_end3]]:
// CHECK-LABEL: ret void
void test_no_merge_if {
if {
f;
}
convfun;
if {
g;
}
}
// CHECK: declare spir_func void @convfun {{[^#]*}} #2
// Test loop is unrolled for convergent function.
// CHECK-LABEL: define{{.*}} spir_func void @test_unroll local_unnamed_addr #1
// CHECK: tail call spir_func void @convfun #[[attr4:[0-9]+]]
// CHECK: tail call spir_func void @convfun #[[attr4]]
// CHECK: tail call spir_func void @convfun #[[attr4]]
// CHECK: tail call spir_func void @convfun #[[attr4]]
// CHECK: tail call spir_func void @convfun #[[attr4]]
// CHECK: tail call spir_func void @convfun #[[attr4]]
// CHECK: tail call spir_func void @convfun #[[attr4]]
// CHECK: tail call spir_func void @convfun #[[attr4]]
// CHECK: tail call spir_func void @convfun #[[attr4]]
// CHECK: tail call spir_func void @convfun #[[attr4]]
// CHECK-LABEL: ret void
void test_unroll {
for local_unnamed_addr #0
// CHECK: ret void
__attribute__
void non_convfun {
volatile int* p