Files
clang-p2996/clang/test/CodeGen/attr-mustprogress-1.cpp
Atmn Patel fd3cad7a60 [clang] Fix ForStmt mustprogress handling
D86841 had an error where for statements with no conditional were
required to make progress. This is not true, this patch removes that
line, and adds regression tests.

Differential Revision: https://reviews.llvm.org/D91075
2020-11-09 11:38:06 -05:00

272 lines
8.1 KiB
C++

// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-attributes
// RUN: %clang_cc1 -std=c++11 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
// RUN: %clang_cc1 -std=c++14 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
// RUN: %clang_cc1 -std=c++17 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
// RUN: %clang_cc1 -std=c++20 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
int a = 0;
int b = 0;
// CHECK: Function Attrs: noinline nounwind optnone
// CHECK-LABEL: @_Z2f0v(
// CHECK-NEXT: entry:
// CHECK-NEXT: br label [[FOR_COND:%.*]]
// CHECK: for.cond:
// CHECK-NOT: br label [[FOR_COND]], !llvm.loop !{{.*}}
void f0() {
for (; ;) ;
}
// CHECK: Function Attrs: noinline nounwind optnone
// CHECK-LABEL: @_Z2f1v(
// 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-NEXT: br label [[FOR_COND]]
// CHECK: for.end:
// CHECK-NEXT: ret void
//
void f1() {
for (; 1;)
;
}
// CHECK: Function Attrs: noinline nounwind optnone mustprogress
// CHECK-LABEL: @_Z2f2v(
// 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:
// CHECK-NEXT: br label [[FOR_COND]], [[LOOP2:!llvm.loop !.*]]
// CHECK: for.end:
// CHECK-NEXT: ret void
//
void f2() {
for (; a == b;)
;
}
// CHECK: Function Attrs: noinline nounwind optnone
// CHECK-LABEL: @_Z1Fv(
// 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-NEXT: br label [[FOR_COND]]
// 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:
// CHECK-NEXT: br label [[FOR_COND1]], [[LOOP4:!llvm.loop !.*]]
// CHECK: for.end3:
// CHECK-NEXT: ret void
//
void F() {
for (; 1;)
;
for (; a == b;)
;
}
// CHECK: Function Attrs: noinline nounwind optnone
// CHECK-LABEL: @_Z2F2v(
// 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:
// CHECK-NEXT: br label [[FOR_COND]], [[LOOP5:!llvm.loop !.*]]
// CHECK: for.end:
// CHECK-NEXT: br label [[FOR_COND1:%.*]]
// CHECK: for.cond1:
// CHECK-NEXT: br i1 true, label [[FOR_BODY2:%.*]], label [[FOR_END3:%.*]]
// CHECK: for.body2:
// CHECK-NEXT: br label [[FOR_COND1]]
// CHECK: for.end3:
// CHECK-NEXT: ret void
//
void F2() {
for (; a == b;)
;
for (; 1;)
;
}
// CHECK: Function Attrs: noinline nounwind optnone
// CHECK-LABEL: @_Z2w1v(
// CHECK-NEXT: entry:
// CHECK-NEXT: br label [[WHILE_BODY:%.*]]
// CHECK: while.body:
// CHECK-NEXT: br label [[WHILE_BODY]]
//
void w1() {
while (1)
;
}
// CHECK: Function Attrs: noinline nounwind optnone mustprogress
// CHECK-LABEL: @_Z2w2v(
// 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:
// CHECK-NEXT: br label [[WHILE_COND]], [[LOOP6:!llvm.loop !.*]]
// CHECK: while.end:
// CHECK-NEXT: ret void
//
void w2() {
while (a == b)
;
}
// CHECK: Function Attrs: noinline nounwind optnone
// CHECK-LABEL: @_Z1Wv(
// 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:
// CHECK-NEXT: br label [[WHILE_COND]], [[LOOP7:!llvm.loop !.*]]
// CHECK: while.end:
// CHECK-NEXT: br label [[WHILE_BODY2:%.*]]
// CHECK: while.body2:
// CHECK-NEXT: br label [[WHILE_BODY2]]
//
void W() {
while (a == b)
;
while (1)
;
}
// CHECK: Function Attrs: noinline nounwind optnone
// CHECK-LABEL: @_Z2W2v(
// CHECK-NEXT: entry:
// CHECK-NEXT: br label [[WHILE_BODY:%.*]]
// CHECK: while.body:
// CHECK-NEXT: br label [[WHILE_BODY]]
//
void W2() {
while (1)
;
while (a == b)
;
}
// CHECK: Function Attrs: noinline nounwind optnone
// CHECK-LABEL: @_Z2d1v(
// CHECK-NEXT: entry:
// CHECK-NEXT: br label [[DO_BODY:%.*]]
// CHECK: do.body:
// CHECK-NEXT: br label [[DO_COND:%.*]]
// CHECK: do.cond:
// CHECK-NEXT: br i1 true, label [[DO_BODY]], label [[DO_END:%.*]]
// CHECK: do.end:
// CHECK-NEXT: ret void
//
void d1() {
do
;
while (1);
}
// CHECK: Function Attrs: noinline nounwind optnone mustprogress
// CHECK-LABEL: @_Z2d2v(
// 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]]
// CHECK-NEXT: br i1 [[CMP]], label [[DO_BODY]], label [[DO_END:%.*]], [[LOOP8:!llvm.loop !.*]]
// CHECK: do.end:
// CHECK-NEXT: ret void
//
void d2() {
do
;
while (a == b);
}
// CHECK: Function Attrs: noinline nounwind optnone
// CHECK-LABEL: @_Z1Dv(
// CHECK-NEXT: entry:
// CHECK-NEXT: br label [[DO_BODY:%.*]]
// CHECK: do.body:
// CHECK-NEXT: br label [[DO_COND:%.*]]
// CHECK: do.cond:
// CHECK-NEXT: br i1 true, label [[DO_BODY]], label [[DO_END:%.*]]
// 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]]
// CHECK-NEXT: br i1 [[CMP]], label [[DO_BODY1]], label [[DO_END3:%.*]], [[LOOP9:!llvm.loop !.*]]
// CHECK: do.end3:
// CHECK-NEXT: ret void
//
void D() {
do
;
while (1);
do
;
while (a == b);
}
// CHECK: Function Attrs: noinline nounwind optnone
// CHECK-LABEL: @_Z2D2v(
// 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]]
// CHECK-NEXT: br i1 [[CMP]], label [[DO_BODY]], label [[DO_END:%.*]], [[LOOP10:!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: br i1 true, label [[DO_BODY1]], label [[DO_END3:%.*]]
// CHECK: do.end3:
// CHECK-NEXT: ret void
//
void D2() {
do
;
while (a == b);
do
;
while (1);
}