diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -796,7 +796,10 @@ if (llvm::ConstantInt *C = dyn_cast(BoolCondVal)) { if (C->isOne()) { EmitBoolCondBranch = false; - FnIsMustProgress = false; + if (CWithProgress()) + FnIsMustProgress = false; + else if (CPlusPlusWithProgress()) + LoopMustProgress = true; } } else if (LanguageRequiresProgress()) LoopMustProgress = true; @@ -897,8 +900,10 @@ if (llvm::ConstantInt *C = dyn_cast(BoolCondVal)) { if (C->isZero()) EmitBoolCondBranch = false; - else if (C->isOne()) + else if (C->isOne() && CWithProgress()) FnIsMustProgress = false; + else if (CPlusPlusWithProgress()) + LoopMustProgress = true; } else if (LanguageRequiresProgress()) LoopMustProgress = true; @@ -945,12 +950,13 @@ bool LoopMustProgress = false; Expr::EvalResult Result; + if (LanguageRequiresProgress()) { - if (!S.getCond()) { + if (!S.getCond() && CWithProgress()) FnIsMustProgress = false; - } else if (!S.getCond()->EvaluateAsInt(Result, getContext())) { + else if (CPlusPlusWithProgress() || + !S.getCond()->EvaluateAsInt(Result, getContext())) LoopMustProgress = true; - } } const SourceRange &R = S.getSourceRange(); @@ -994,7 +1000,7 @@ S.getCond(), getProfileCount(S.getBody()), S.getBody()); if (llvm::ConstantInt *C = dyn_cast(BoolCondVal)) - if (C->isOne()) + if (C->isOne() && CWithProgress()) FnIsMustProgress = false; Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock, Weights); diff --git a/clang/test/CodeGen/attr-mustprogress-1.cpp b/clang/test/CodeGen/attr-mustprogress-1.cpp --- a/clang/test/CodeGen/attr-mustprogress-1.cpp +++ b/clang/test/CodeGen/attr-mustprogress-1.cpp @@ -7,24 +7,25 @@ int a = 0; int b = 0; -// CHECK: Function Attrs: noinline nounwind optnone +// CHECK: Function Attrs: noinline nounwind optnone mustprogress // CHECK-LABEL: @_Z2f0v( // CHECK-NEXT: entry: // CHECK-NEXT: br label [[FOR_COND:%.*]] // CHECK: for.cond: -// CHECK-NOT: br label [[FOR_COND]], !llvm.loop !{{.*}} +// CHECK-NEXT: br label [[FOR_COND]], [[LOOP2:!llvm.loop !.*]] +// void f0() { for (; ;) ; } -// CHECK: Function Attrs: noinline nounwind optnone +// CHECK: Function Attrs: noinline nounwind optnone mustprogress // 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-NEXT: br label [[FOR_COND]], [[LOOP4:!llvm.loop !.*]] // CHECK: for.end: // CHECK-NEXT: ret void // @@ -43,7 +44,7 @@ // 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-NEXT: br label [[FOR_COND]], [[LOOP5:!llvm.loop !.*]] // CHECK: for.end: // CHECK-NEXT: ret void // @@ -52,14 +53,14 @@ ; } -// CHECK: Function Attrs: noinline nounwind optnone +// CHECK: Function Attrs: noinline nounwind optnone mustprogress // 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-NEXT: br label [[FOR_COND]], [[LOOP6:!llvm.loop !.*]] // CHECK: for.end: // CHECK-NEXT: br label [[FOR_COND1:%.*]] // CHECK: for.cond1: @@ -68,7 +69,7 @@ // 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-NEXT: br label [[FOR_COND1]], [[LOOP7:!llvm.loop !.*]] // CHECK: for.end3: // CHECK-NEXT: ret void // @@ -79,7 +80,7 @@ ; } -// CHECK: Function Attrs: noinline nounwind optnone +// CHECK: Function Attrs: noinline nounwind optnone mustprogress // CHECK-LABEL: @_Z2F2v( // CHECK-NEXT: entry: // CHECK-NEXT: br label [[FOR_COND:%.*]] @@ -89,13 +90,13 @@ // 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-NEXT: br label [[FOR_COND]], [[LOOP8:!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-NEXT: br label [[FOR_COND1]], [[LOOP9:!llvm.loop !.*]] // CHECK: for.end3: // CHECK-NEXT: ret void // @@ -106,12 +107,12 @@ ; } -// CHECK: Function Attrs: noinline nounwind optnone +// CHECK: Function Attrs: noinline nounwind optnone mustprogress // CHECK-LABEL: @_Z2w1v( // CHECK-NEXT: entry: // CHECK-NEXT: br label [[WHILE_BODY:%.*]] // CHECK: while.body: -// CHECK-NEXT: br label [[WHILE_BODY]] +// CHECK-NEXT: br label [[WHILE_BODY]], [[LOOP10:!llvm.loop !.*]] // void w1() { while (1) @@ -128,7 +129,7 @@ // 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-NEXT: br label [[WHILE_COND]], [[LOOP11:!llvm.loop !.*]] // CHECK: while.end: // CHECK-NEXT: ret void // @@ -137,7 +138,7 @@ ; } -// CHECK: Function Attrs: noinline nounwind optnone +// CHECK: Function Attrs: noinline nounwind optnone mustprogress // CHECK-LABEL: @_Z1Wv( // CHECK-NEXT: entry: // CHECK-NEXT: br label [[WHILE_COND:%.*]] @@ -147,11 +148,11 @@ // 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-NEXT: br label [[WHILE_COND]], [[LOOP12:!llvm.loop !.*]] // CHECK: while.end: // CHECK-NEXT: br label [[WHILE_BODY2:%.*]] // CHECK: while.body2: -// CHECK-NEXT: br label [[WHILE_BODY2]] +// CHECK-NEXT: br label [[WHILE_BODY2]], [[LOOP13:!llvm.loop !.*]] // void W() { while (a == b) @@ -160,12 +161,12 @@ ; } -// CHECK: Function Attrs: noinline nounwind optnone +// CHECK: Function Attrs: noinline nounwind optnone mustprogress // CHECK-LABEL: @_Z2W2v( // CHECK-NEXT: entry: // CHECK-NEXT: br label [[WHILE_BODY:%.*]] // CHECK: while.body: -// CHECK-NEXT: br label [[WHILE_BODY]] +// CHECK-NEXT: br label [[WHILE_BODY]], [[LOOP14:!llvm.loop !.*]] // void W2() { while (1) @@ -174,14 +175,14 @@ ; } -// CHECK: Function Attrs: noinline nounwind optnone +// CHECK: Function Attrs: noinline nounwind optnone mustprogress // 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-NEXT: br i1 true, label [[DO_BODY]], label [[DO_END:%.*]], [[LOOP15:!llvm.loop !.*]] // CHECK: do.end: // CHECK-NEXT: ret void // @@ -201,7 +202,7 @@ // 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-NEXT: br i1 [[CMP]], label [[DO_BODY]], label [[DO_END:%.*]], [[LOOP16:!llvm.loop !.*]] // CHECK: do.end: // CHECK-NEXT: ret void // @@ -211,14 +212,14 @@ while (a == b); } -// CHECK: Function Attrs: noinline nounwind optnone +// CHECK: Function Attrs: noinline nounwind optnone mustprogress // 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-NEXT: br i1 true, label [[DO_BODY]], label [[DO_END:%.*]], [[LOOP17:!llvm.loop !.*]] // CHECK: do.end: // CHECK-NEXT: br label [[DO_BODY1:%.*]] // CHECK: do.body1: @@ -227,7 +228,7 @@ // 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-NEXT: br i1 [[CMP]], label [[DO_BODY1]], label [[DO_END3:%.*]], [[LOOP18:!llvm.loop !.*]] // CHECK: do.end3: // CHECK-NEXT: ret void // @@ -240,7 +241,7 @@ while (a == b); } -// CHECK: Function Attrs: noinline nounwind optnone +// CHECK: Function Attrs: noinline nounwind optnone mustprogress // CHECK-LABEL: @_Z2D2v( // CHECK-NEXT: entry: // CHECK-NEXT: br label [[DO_BODY:%.*]] @@ -250,13 +251,13 @@ // 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-NEXT: br i1 [[CMP]], label [[DO_BODY]], label [[DO_END:%.*]], [[LOOP19:!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-NEXT: br i1 true, label [[DO_BODY1]], label [[DO_END3:%.*]], [[LOOP20:!llvm.loop !.*]] // CHECK: do.end3: // CHECK-NEXT: ret void //