// RUN: %clang_cc1 -std=c99 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK --check-prefix=C99 %s // RUN: %clang_cc1 -std=c11 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK --check-prefix=C11 %s // RUN: %clang_cc1 -std=c18 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK --check-prefix=C11 %s // RUN: %clang_cc1 -std=c2x -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK --check-prefix=C11 %s // // RUN: %clang_cc1 -std=c11 -ffinite-loops -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK --check-prefix=FINITE %s // RUN: %clang_cc1 -std=c11 -fno-finite-loops -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck --check-prefix=CHECK --check-prefix=C99 %s int a = 0; int b = 0; // CHECK: datalayout // // CHECK-NOT: mustprogress // CHECK-LABEL: @f0( // CHECK-NEXT: entry: // CHECK-NEXT: br label %for.cond // CHECK: for.cond: // CHECK-NOT: br {{.*}}!llvm.loop // void f0() { for (; ;) ; } // CHECK-NOT: mustprogress // CHECK-LABEL: @f1( // CHECK-NEXT: entry: // CHECK-NEXT: br label %for.cond // CHECK: for.cond: // CHECK-NEXT: br i1 true, label %for.body, label %for.end // CHECK: for.body: // CHECK-NOT: br {{.*}}, !llvm.loop // CHECK: for.end: // CHECK-NEXT: ret void // void f1() { for (; 1;) { } } // CHECK-NOT: mustprogress // CHECK-LABEL: @f2( // CHECK-NEXT: entry: // CHECK-NEXT: br label %for.cond // CHECK: for.cond: // CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4 // CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4 // CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]] // CHECK-NEXT: br i1 [[CMP]], label %for.body, label %for.end // CHECK: for.body: // C99-NOT: br {{.*}} !llvm.loop // C11: br label %for.cond, !llvm.loop [[LOOP1:!.*]] // FINITE: br label %for.cond, !llvm.loop [[LOOP1:!.*]] // CHECK: for.end: // CHECK-NEXT: ret void // void f2() { for (; a == b;) { } } // CHECK-NOT: mustprogress // CHECK-LABEL: @F( // CHECK-NEXT: entry: // CHECK-NEXT: br label %for.cond // CHECK: for.cond: // CHECK-NEXT: br i1 true, label %for.body, label %for.end // CHECK: for.body: // CHECK-NOT: br {{.*}}, !llvm.loop // CHECK: for.end: // CHECK-NEXT: br label %for.cond1 // CHECK: for.cond1: // CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4 // CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4 // CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]] // CHECK-NEXT: br i1 [[CMP]], label %for.body2, label %for.end3 // CHECK: for.body2: // C99-NOT: br {{.*}}, !llvm.loop // C11: br label %for.cond1, !llvm.loop [[LOOP2:!.*]] // FINITE: br label %for.cond1, !llvm.loop [[LOOP2:!.*]] // CHECK: for.end3: // CHECK-NEXT: ret void // void F() { for (; 1;) { } for (; a == b;) { } } // CHECK-NOT: mustprogress // CHECK-LABEL: @w1( // CHECK-NEXT: entry: // CHECK-NEXT: br label %while.body // CHECK: while.body: // CHECK-NOT: br {{.*}}, !llvm.loop // void w1() { while (1) { } } // CHECK-NOT: mustprogress // CHECK-LABEL: @w2( // CHECK-NEXT: entry: // CHECK-NEXT: br label %while.cond // CHECK: while.cond: // CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4 // CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4 // CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]] // CHECK-NEXT: br i1 [[CMP]], label %while.body, label %while.end // CHECK: while.body: // C99-NOT: br {{.*}}, !llvm.loop // C11: br label %while.cond, !llvm.loop [[LOOP3:!.*]] // FINITE: br label %while.cond, !llvm.loop [[LOOP3:!.*]] // CHECK: while.end: // CHECK-NEXT: ret void // void w2() { while (a == b) { } } // CHECK-NOT: mustprogress // CHECK-LABEL: @W( // CHECK-NEXT: entry: // CHECK-NEXT: br label [[WHILE_COND:%.*]] // CHECK: while.cond: // CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4 // CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4 // CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]] // CHECK-NEXT: br i1 [[CMP]], label %while.body, label %while.end // CHECK: while.body: // C99-NOT: br {{.*}} !llvm.loop // C11: br label %while.cond, !llvm.loop [[LOOP4:!.*]] // FINITE: br label %while.cond, !llvm.loop [[LOOP4:!.*]] // CHECK: while.end: // CHECK-NEXT: br label %while.body2 // CHECK: while.body2: // CHECK-NOT: br {{.*}} !llvm.loop // void W() { while (a == b) { } while (1) { } } // CHECK-NOT: mustprogress // CHECK-LABEL: @d1( // CHECK-NEXT: entry: // CHECK-NEXT: br label %do.body // CHECK: do.body: // CHECK-NEXT: br label %do.cond // CHECK: do.cond: // CHECK-NOT: br {{.*}}, !llvm.loop // CHECK: do.end: // CHECK-NEXT: ret void // void d1() { do { } while (1); } // CHECK-NOT: mustprogress // CHECK-LABEL: @d2( // CHECK-NEXT: entry: // CHECK-NEXT: br label %do.body // CHECK: do.body: // CHECK-NEXT: br label %do.cond // CHECK: do.cond: // CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4 // CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4 // CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]] // C99-NOT: br {{.*}}, !llvm.loop // C11: br i1 [[CMP]], label %do.body, label %do.end, !llvm.loop [[LOOP5:!.*]] // FINITE: br i1 [[CMP]], label %do.body, label %do.end, !llvm.loop [[LOOP5:!.*]] // CHECK: do.end: // CHECK-NEXT: ret void // void d2() { do { } while (a == b); } // CHECK-NOT: mustprogress // CHECK-LABEL: @D( // CHECK-NEXT: entry: // CHECK-NEXT: br label %do.body // CHECK: do.body: // CHECK-NEXT: br label %do.cond // CHECK: do.cond: // CHECK-NOT: br label {{.*}}, !llvm.loop // CHECK: do.end: // CHECK-NEXT: br label %do.body1 // CHECK: do.body1: // CHECK-NEXT: br label %do.cond2 // CHECK: do.cond2: // CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4 // CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4 // CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]] // C99-NOT: br {{.*}}, !llvm.loop // C11: br i1 [[CMP]], label %do.body1, label %do.end3, !llvm.loop [[LOOP6:!.*]] // FINITE: br i1 [[CMP]], label %do.body1, label %do.end3, !llvm.loop [[LOOP6:!.*]] // CHECK: do.end3: // CHECK-NEXT: ret void // void D() { do { } while (1); do { } while (a == b); } // C11: [[LOOP1]] = distinct !{[[LOOP1]], [[MP:!.*]]} // C11: [[MP]] = !{!"llvm.loop.mustprogress"} // C11: [[LOOP2]] = distinct !{[[LOOP2]], [[MP]]} // C11: [[LOOP3]] = distinct !{[[LOOP3]], [[MP]]} // C11: [[LOOP4]] = distinct !{[[LOOP4]], [[MP]]} // C11: [[LOOP5]] = distinct !{[[LOOP5]], [[MP]]} // C11: [[LOOP6]] = distinct !{[[LOOP6]], [[MP]]}