[CodeGen] Implement [[likely]] and [[unlikely]] for while and for loop.
The attribute has no effect on a do statement since the path of execution
will always include its substatement.
It adds a diagnostic when the attribute is used on an infinite while loop
since the codegen omits the branch here. Since the likelihood attributes
have no effect on a do statement no diagnostic will be issued for
do [[unlikely]] {...} while(0);
Differential Revision: https://reviews.llvm.org/D89899
diff --git a/clang/test/CodeGenCXX/attr-likelihood-iteration-stmt.cpp b/clang/test/CodeGenCXX/attr-likelihood-iteration-stmt.cpp
new file mode 100644
index 0000000..1c87ee4
--- /dev/null
+++ b/clang/test/CodeGenCXX/attr-likelihood-iteration-stmt.cpp
@@ -0,0 +1,60 @@
+// RUN: %clang_cc1 -O1 -disable-llvm-passes -emit-llvm %s -o - -triple=x86_64-linux-gnu -verify
+// RUN: %clang_cc1 -O1 -disable-llvm-passes -emit-llvm %s -o - -triple=x86_64-linux-gnu | FileCheck %s
+
+void wl(int e){
+ // CHECK-LABEL: define{{.*}}wl
+ // CHECK: br {{.*}} !prof !6
+ while(e) [[likely]] ++e;
+}
+
+void wu(int e){
+ // CHECK-LABEL: define{{.*}}wu
+ // CHECK: br {{.*}} !prof !9
+ while(e) [[unlikely]] ++e;
+}
+
+void w_branch_elided(unsigned e){
+ // CHECK-LABEL: define{{.*}}w_branch_elided
+ // CHECK-NOT: br {{.*}} !prof
+ // expected-warning@+2 {{attribute 'likely' has no effect when annotating an infinite loop}}
+ // expected-note@+1 {{annotating the infinite loop here}}
+ while(1) [[likely]] ++e;
+}
+
+void fl(unsigned e)
+{
+ // CHECK-LABEL: define{{.*}}fl
+ // CHECK: br {{.*}} !prof !6
+ for(int i = 0; i != e; ++e) [[likely]];
+}
+
+void fu(int e)
+{
+ // CHECK-LABEL: define{{.*}}fu
+ // CHECK: br {{.*}} !prof !9
+ for(int i = 0; i != e; ++e) [[unlikely]];
+}
+
+void f_branch_elided()
+{
+ // CHECK-LABEL: define{{.*}}f_branch_elided
+ // CHECK-NOT: br {{.*}} !prof
+ for(;;) [[likely]];
+}
+
+void frl(int (&&e) [4])
+{
+ // CHECK-LABEL: define{{.*}}frl
+ // CHECK: br {{.*}} !prof !6
+ for(int i : e) [[likely]];
+}
+
+void fru(int (&&e) [4])
+{
+ // CHECK-LABEL: define{{.*}}fru
+ // CHECK: br {{.*}} !prof !9
+ for(int i : e) [[unlikely]];
+}
+
+// CHECK: !6 = !{!"branch_weights", i32 2000, i32 1}
+// CHECK: !9 = !{!"branch_weights", i32 1, i32 2000}