Skip to content

Commit a6d4be0

Browse files
committed
[MC/DC] Update CoverageMapping tests
To resolve the error, rename mcdc-error-nests.cpp -> mcdc-nested-expr.cpp at first. - `func_condop` A corner case that contains close decisions. - `func_expect` Uses `__builtin_expect`. (#124565) - `func_lnot` Contains logical not(s) `!` among MC/DC binary operators. (#124563) mcdc-single-cond.cpp is for #95336.
1 parent fffa68a commit a6d4be0

File tree

3 files changed

+131
-10
lines changed

3 files changed

+131
-10
lines changed

clang/test/CoverageMapping/mcdc-error-nests.cpp

Lines changed: 0 additions & 10 deletions
This file was deleted.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++11 -fcoverage-mcdc -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only %s 2> %t.stderr.txt | FileCheck %s
2+
// RUN: FileCheck %s --check-prefix=WARN < %t.stderr.txt
3+
4+
// "Split-nest" -- boolean expressions within boolean expressions.
5+
extern bool bar(bool);
6+
// CHECK: func_split_nest{{.*}}:
7+
bool func_split_nest(bool a, bool b, bool c, bool d, bool e, bool f, bool g) {
8+
// WARN: :[[@LINE+1]]:14: warning: unsupported MC/DC boolean expression; contains an operation with a nested boolean expression.
9+
bool res = a && b && c && bar(d && e) && f && g;
10+
return bar(res);
11+
}
12+
13+
// The inner expr begins with the same Loc as the outer expr
14+
// CHECK: func_condop{{.*}}:
15+
bool func_condop(bool a, bool b, bool c) {
16+
// WARN: :[[@LINE+1]]:10: warning: unsupported MC/DC boolean expression; contains an operation with a nested boolean expression.
17+
return (a && b ? true : false) && c;
18+
}
19+
20+
// __builtin_expect
21+
// Treated as parentheses.
22+
// CHECK: func_expect{{.*}}:
23+
bool func_expect(bool a, bool b, bool c) {
24+
// WARN: :[[@LINE+1]]:10: warning: unsupported MC/DC boolean expression; contains an operation with a nested boolean expression.
25+
return a || __builtin_expect(b && c, true);
26+
}
27+
28+
// LNot among BinOp(s)
29+
// Doesn't split exprs.
30+
// CHECK: func_lnot{{.*}}:
31+
bool func_lnot(bool a, bool b, bool c, bool d) {
32+
// WARN: :[[@LINE+1]]:10: warning: unsupported MC/DC boolean expression; contains an operation with a nested boolean expression.
33+
return !(a || b) && !(c && d);
34+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++11 -fcoverage-mcdc -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -disable-llvm-passes -emit-llvm -o %t2.ll %s | FileCheck %s --check-prefixes=MM,MM2
2+
// RUN: FileCheck %s --check-prefixes=LL,LL2 < %t2.ll
3+
4+
// LL: define{{.+}}func_cond{{.+}}(
5+
// MM: func_cond{{.*}}:
6+
int func_cond(bool a, bool b) {
7+
// %mcdc.addr* are emitted by static order.
8+
// LL: %[[MA:mcdc.addr.*]] = alloca i32, align 4
9+
// LL: call void @llvm.instrprof.mcdc.parameters(ptr @[[PROFN:.+]], i64 [[#H:]], i32 [[#BS:]])
10+
int count = 0;
11+
if (a)
12+
// NB=2 Single cond
13+
// MM2-NOT: Decision
14+
++count;
15+
if (a ? true : false)
16+
// NB=2,2 Wider decision comes first.
17+
// MA2 has C:2
18+
// MA3 has C:1
19+
++count;
20+
if (a && b ? true : false)
21+
// NB=2,3 Wider decision comes first.
22+
// MM2: Decision,File 0, [[@LINE-2]]:7 -> [[#L:@LINE-2]]:13 = M:[[#I:3]], C:2
23+
// MM: Branch,File 0, [[#L]]:7 -> [[#L]]:8 = #6, (#0 - #6) [1,2,0]
24+
// MM: Branch,File 0, [[#L]]:12 -> [[#L]]:13 = #7, (#6 - #7) [2,0,0]
25+
// LL: store i32 0, ptr %[[MA]], align 4
26+
// LL: = load i32, ptr %[[MA]], align 4
27+
// LL: store i32 %{{.+}}, ptr %[[MA]], align 4
28+
// LL: = load i32, ptr %[[MA]], align 4
29+
// LL: store i32 %{{.+}}, ptr %[[MA]], align 4
30+
// LL2: call void @llvm.instrprof.mcdc.tvbitmap.update(ptr @[[PROFN]], i64 [[#H]], i32 [[#B:0]], ptr %[[MA]])
31+
++count;
32+
while (a || true) {
33+
// NB=3 BinOp only
34+
// MM: Decision,File 0, [[@LINE-2]]:10 -> [[#L:@LINE-2]]:19 = M:[[#I:I+3]], C:2
35+
// MM: Branch,File 0, [[#L]]:10 -> [[#L]]:11 = (#0 - #9), #9 [1,0,2]
36+
// MM: Branch,File 0, [[#L]]:15 -> [[#L]]:19 = (#9 - #10), 0 [2,0,0]
37+
// LL: store i32 0, ptr %[[MA]], align 4
38+
// LL: = load i32, ptr %[[MA]], align 4
39+
// LL: store i32 %{{.+}}, ptr %[[MA]], align 4
40+
// LL: = load i32, ptr %[[MA]], align 4
41+
// LL: store i32 %{{.+}}, ptr %[[MA]], align 4
42+
// LL2: call void @llvm.instrprof.mcdc.tvbitmap.update(ptr @[[PROFN]], i64 [[#H]], i32 [[#B:B+3]], ptr %[[MA]])
43+
++count;
44+
break;
45+
}
46+
while (a || true ? false : true) {
47+
// Wider decision comes first.
48+
// MM2: Decision,File 0, [[@LINE-2]]:10 -> [[#L:@LINE-2]]:19 = M:[[#I:I+3]], C:2
49+
// MM: Branch,File 0, [[#L]]:10 -> [[#L]]:11 = ((#0 + #11) - #13), #13 [1,0,2]
50+
// MM: Branch,File 0, [[#L]]:15 -> [[#L]]:19 = (#13 - #14), 0 [2,0,0]
51+
// LL: store i32 0, ptr %[[MA]], align 4
52+
// LL: = load i32, ptr %[[MA]], align 4
53+
// LL: store i32 %{{.+}}, ptr %[[MA]], align 4
54+
// LL: = load i32, ptr %[[MA]], align 4
55+
// LL: store i32 %{{.+}}, ptr %[[MA]], align 4
56+
// LL: call void @llvm.instrprof.mcdc.tvbitmap.update(ptr @[[PROFN]], i64 [[#H]], i32 [[#B:B+3]], ptr %[[MA]])
57+
++count;
58+
}
59+
do {
60+
++count;
61+
} while (a && false);
62+
// BinOp only
63+
// MM: Decision,File 0, [[@LINE-2]]:12 -> [[#L:@LINE-2]]:22 = M:[[#I:I+3]], C:2
64+
// MM: Branch,File 0, [[#L]]:12 -> [[#L]]:13 = #16, ((#0 + #15) - #16) [1,2,0]
65+
// MM: Branch,File 0, [[#L]]:17 -> [[#L]]:22 = 0, (#16 - #17) [2,0,0]
66+
// LL: store i32 0, ptr %[[MA]], align 4
67+
// LL: = load i32, ptr %[[MA]], align 4
68+
// LL: store i32 %{{.+}}, ptr %[[MA]], align 4
69+
// LL: = load i32, ptr %[[MA]], align 4
70+
// LL: store i32 %{{.+}}, ptr %[[MA]], align 4
71+
// LL2: call void @llvm.instrprof.mcdc.tvbitmap.update(ptr @[[PROFN]], i64 [[#H]], i32 [[#B:B+3]], ptr %[[MA]])
72+
do {
73+
++count;
74+
} while (a && false ? true : false);
75+
// Wider decision comes first.
76+
// MM2: Decision,File 0, [[@LINE-2]]:12 -> [[#L:@LINE-2]]:22 = M:15, C:2
77+
// MM: Branch,File 0, [[#L]]:12 -> [[#L]]:13 = #20, ((#0 + #18) - #20) [1,2,0]
78+
// MM: Branch,File 0, [[#L]]:17 -> [[#L]]:22 = 0, (#20 - #21) [2,0,0]
79+
// LL: store i32 0, ptr %[[MA]], align 4
80+
// LL: = load i32, ptr %[[MA]], align 4
81+
// LL: store i32 %{{.+}}, ptr %[[MA]], align 4
82+
// LL: = load i32, ptr %[[MA]], align 4
83+
// LL: store i32 %{{.+}}, ptr %[[MA]], align 4
84+
// LL: call void @llvm.instrprof.mcdc.tvbitmap.update(ptr @[[PROFN]], i64 [[#H]], i32 [[#B:B+3]], ptr %[[MA]])
85+
// FIXME: Confirm (B+3==BS)
86+
for (int i = 0; i < (a ? 2 : 1); ++i) {
87+
// Simple nested decision (different column)
88+
// MM2-NOT: Decision
89+
// LL2-NOT: call void @llvm.instrprof.mcdc.tvbitmap.update
90+
++count;
91+
}
92+
for (int i = 0; i >= 4 ? false : true; ++i) {
93+
// Wider decision comes first.
94+
++count;
95+
}
96+
return count;
97+
}

0 commit comments

Comments
 (0)