greened updated this revision to Diff 279932.
greened added a comment.
Updated to move the option into `common.py`. Also had to rework the output
loop to account for differences between python 2 and 3.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D83004/new/
https://reviews.llvm.org/D83004
Files:
clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c
clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.generated.expected
clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.no-generated.expected
clang/test/utils/update_cc_test_checks/generated-funcs.test
llvm/utils/UpdateTestChecks/asm.py
llvm/utils/UpdateTestChecks/common.py
llvm/utils/update_cc_test_checks.py
llvm/utils/update_llc_test_checks.py
llvm/utils/update_test_checks.py
Index: llvm/utils/update_test_checks.py
===================================================================
--- llvm/utils/update_test_checks.py
+++ llvm/utils/update_test_checks.py
@@ -137,9 +137,11 @@
prefix_list.append((check_prefixes, tool_cmd_args))
func_dict = {}
+ func_order = {}
for prefixes, _ in prefix_list:
for prefix in prefixes:
func_dict.update({prefix: dict()})
+ func_order.update({prefix: []})
for prefixes, opt_args in prefix_list:
common.debug('Extracted opt cmd: ' + opt_basename + ' ' + opt_args)
common.debug('Extracted FileCheck prefixes: ' + str(prefixes))
@@ -147,7 +149,7 @@
raw_tool_output = common.invoke_tool(args.opt_binary, opt_args, test)
common.build_function_body_dictionary(
common.OPT_FUNCTION_RE, common.scrub_body, [],
- raw_tool_output, prefixes, func_dict, args.verbose,
+ raw_tool_output, prefixes, func_dict, func_order, args.verbose,
args.function_signature)
is_in_function = False
Index: llvm/utils/update_llc_test_checks.py
===================================================================
--- llvm/utils/update_llc_test_checks.py
+++ llvm/utils/update_llc_test_checks.py
@@ -123,10 +123,12 @@
autogenerated_note = (comment_sym + ADVERT + 'utils/' + script_name)
func_dict = {}
+ func_order = {}
for p in run_list:
prefixes = p[0]
for prefix in prefixes:
func_dict.update({prefix: dict()})
+ func_order.update({prefix: []})
for prefixes, llc_args, triple_in_cmd, march_in_cmd in run_list:
common.debug('Extracted LLC cmd:', llc_tool, llc_args)
common.debug('Extracted FileCheck prefixes:', str(prefixes))
@@ -138,7 +140,7 @@
triple = asm.get_triple_from_march(march_in_cmd)
asm.build_function_body_dictionary_for_triple(args, raw_tool_output,
- triple, prefixes, func_dict)
+ triple, prefixes, func_dict, func_order)
is_in_function = False
is_in_function_start = False
Index: llvm/utils/update_cc_test_checks.py
===================================================================
--- llvm/utils/update_cc_test_checks.py
+++ llvm/utils/update_cc_test_checks.py
@@ -168,7 +168,8 @@
return args
-def get_function_body(args, filename, clang_args, extra_commands, prefixes, triple_in_cmd, func_dict):
+def get_function_body(args, filename, clang_args, extra_commands, prefixes,
+ triple_in_cmd, func_dict, func_order):
# TODO Clean up duplication of asm/common build_function_body_dictionary
# Invoke external tool and extract function bodies.
raw_tool_output = common.invoke_tool(args.clang, clang_args, filename)
@@ -188,7 +189,8 @@
if '-emit-llvm' in clang_args:
common.build_function_body_dictionary(
common.OPT_FUNCTION_RE, common.scrub_body, [],
- raw_tool_output, prefixes, func_dict, args.verbose, args.function_signature)
+ raw_tool_output, prefixes, func_dict, func_order, args.verbose,
+ args.function_signature)
else:
print('The clang command line should include -emit-llvm as asm tests '
'are discouraged in Clang testsuite.', file=sys.stderr)
@@ -267,15 +269,18 @@
# Execute clang, generate LLVM IR, and extract functions.
func_dict = {}
+ func_order = {}
for p in run_list:
prefixes = p[0]
for prefix in prefixes:
func_dict.update({prefix: dict()})
+ func_order.update({prefix: []})
for prefixes, clang_args, extra_commands, triple_in_cmd in run_list:
common.debug('Extracted clang cmd: clang {}'.format(clang_args))
common.debug('Extracted FileCheck prefixes: {}'.format(prefixes))
- get_function_body(args, filename, clang_args, extra_commands, prefixes, triple_in_cmd, func_dict)
+ get_function_body(args, filename, clang_args, extra_commands, prefixes,
+ triple_in_cmd, func_dict, func_order)
# Invoke clang -Xclang -ast-dump=json to get mapping from start lines to
# mangled names. Forward all clang args for now.
@@ -283,29 +288,81 @@
line2spell_and_mangled_list[k].append(v)
output_lines = [autogenerated_note]
- for idx, line in enumerate(input_lines):
- # Discard any previous script advertising.
- if line.startswith(ADVERT):
- continue
- if idx in line2spell_and_mangled_list:
- added = set()
- for spell, mangled in line2spell_and_mangled_list[idx]:
- # One line may contain multiple function declarations.
- # Skip if the mangled name has been added before.
- # The line number may come from an included file,
- # we simply require the spelling name to appear on the line
- # to exclude functions from other files.
- if mangled in added or spell not in line:
- continue
- if args.functions is None or any(re.search(regex, spell) for regex in args.functions):
+
+ if args.include_generated_funcs:
+ # Generate the appropriate checks for each function. We need to emit
+ # these in the order according to the generated output so that CHECK-LABEL
+ # works properly. func_order provides that.
+
+ # It turns out that when clang generates functions (for example, with
+ # -fopenmp), it can sometimes cause functions to be re-ordered in the
+ # output, even functions that exist in the source file. Therefore we
+ # can't insert check lines before each source function and instead have to
+ # put them at the end. So the first thing to do is dump out the source
+ # lines.
+ for idx, line in enumerate(input_lines):
+ # Discard any previous script advertising.
+ if line.startswith(ADVERT):
+ continue
+ output_lines.append(line.rstrip('\n'))
+
+ # Now generate all the checks.
+ added = set()
+ for prefixes, clang_args, extra_commands, triple_in_cmd in run_list:
+ for prefix in prefixes:
+ for func in func_order[prefix]:
if added:
output_lines.append('//')
- added.add(mangled)
- common.add_ir_checks(output_lines, '//', run_list, func_dict, mangled,
- False, args.function_signature)
- output_lines.append(line.rstrip('\n'))
-
-
+ added.add(func)
+
+ # The add_*_checks routines expect a run list whose items are
+ # tuples that have a list of prefixes as their first element and
+ # tool command args string as their second element. They output
+ # checks for each prefix in the list of prefixes. By doing so, it
+ # implicitly assumes that for each function every run line will
+ # generate something for that function. That is not the case for
+ # generated functions as some run lines might not generate them
+ # (e.g. -fopenmp vs. no -fopenmp).
+ #
+ # Therefore, pass just the prefix we're interested in. This has
+ # the effect of generating all of the checks for functions of a
+ # single prefix before moving on to the next prefix. So checks
+ # are ordered by prefix instead of by function as in "normal"
+ # mode.
+ if '-emit-llvm' in clang_args:
+ common.add_ir_checks(output_lines, '//',
+ [([prefix], clang_args)],
+ func_dict, func, False,
+ args.function_signature)
+ else:
+ asm.add_asm_checks(output_lines, '//',
+ [([prefix], clang_args)],
+ func_dict, func)
+ else:
+ # Normal mode. Put checks before each source function.
+ for idx, line in enumerate(input_lines):
+ # Discard any previous script advertising.
+ if line.startswith(ADVERT):
+ continue
+ if idx in line2spell_and_mangled_list:
+ added = set()
+ for spell, mangled in line2spell_and_mangled_list[idx]:
+ # One line may contain multiple function declarations.
+ # Skip if the mangled name has been added before.
+ # The line number may come from an included file,
+ # we simply require the spelling name to appear on the line
+ # to exclude functions from other files.
+ if mangled in added or spell not in line:
+ continue
+ if args.functions is None or any(re.search(regex, spell) for regex in args.functions):
+ if added:
+ output_lines.append('//')
+ added.add(mangled)
+ common.add_ir_checks(output_lines, '//', run_list, func_dict,
+ mangled, False, args.function_signature)
+ output_lines.append(line.rstrip('\n'))
+
+ # Update the test file.
common.debug('Writing %d lines to %s...' % (len(output_lines), filename))
with open(filename, 'wb') as f:
f.writelines(['{}\n'.format(l).encode('utf-8') for l in output_lines])
Index: llvm/utils/UpdateTestChecks/common.py
===================================================================
--- llvm/utils/UpdateTestChecks/common.py
+++ llvm/utils/UpdateTestChecks/common.py
@@ -17,6 +17,8 @@
_verbose = False
def parse_commandline_args(parser):
+ parser.add_argument('--include-generated-funcs', action='store_true',
+ help='Output checks for functions not in source')
parser.add_argument('-v', '--verbose', action='store_true',
help='Show verbose output')
parser.add_argument('-u', '--update-only', action='store_true',
@@ -169,7 +171,7 @@
def __str__(self):
return self.scrub
-def build_function_body_dictionary(function_re, scrubber, scrubber_args, raw_tool_output, prefixes, func_dict, verbose, record_args):
+def build_function_body_dictionary(function_re, scrubber, scrubber_args, raw_tool_output, prefixes, func_dict, func_order, verbose, record_args):
for m in function_re.finditer(raw_tool_output):
if not m:
continue
@@ -209,6 +211,7 @@
continue
func_dict[prefix][func] = function_body(scrubbed_body, scrubbed_extra, args_and_sig)
+ func_order[prefix].append(func)
##### Generator of LLVM IR CHECK lines
Index: llvm/utils/UpdateTestChecks/asm.py
===================================================================
--- llvm/utils/UpdateTestChecks/asm.py
+++ llvm/utils/UpdateTestChecks/asm.py
@@ -321,7 +321,8 @@
print("Cannot find a triple. Assume 'x86'", file=sys.stderr)
return 'x86'
-def build_function_body_dictionary_for_triple(args, raw_tool_output, triple, prefixes, func_dict):
+def build_function_body_dictionary_for_triple(args, raw_tool_output, triple,
+ prefixes, func_dict, func_order):
target_handlers = {
'i686': (scrub_asm_x86, ASM_FUNCTION_X86_RE),
'x86': (scrub_asm_x86, ASM_FUNCTION_X86_RE),
@@ -364,7 +365,7 @@
scrubber, function_re = handler
common.build_function_body_dictionary(
function_re, scrubber, [args], raw_tool_output, prefixes,
- func_dict, args.verbose, False)
+ func_dict, func_order, args.verbose, False)
##### Generator of assembly CHECK lines
Index: clang/test/utils/update_cc_test_checks/generated-funcs.test
===================================================================
--- /dev/null
+++ clang/test/utils/update_cc_test_checks/generated-funcs.test
@@ -0,0 +1,11 @@
+## Test that CHECK lines are generated for clang-generated functions
+
+# RUN: cp %S/Inputs/generated-funcs.c %t-generated.c && %update_cc_test_checks --include-generated-funcs %t-generated.c
+# RUN: diff -u %S/Inputs/generated-funcs.c.generated.expected %t-generated.c
+# RUN: cp %S/Inputs/generated-funcs.c %t-no-generated.c && %update_cc_test_checks %t-no-generated.c
+# RUN: diff -u %S/Inputs/generated-funcs.c.no-generated.expected %t-no-generated.c
+## Check that re-running update_cc_test_checks doesn't change the output
+# RUN: %update_cc_test_checks --include-generated-funcs %t-generated.c
+# RUN: diff -u %S/Inputs/generated-funcs.c.generated.expected %t-generated.c
+# RUN: %update_cc_test_checks %t-no-generated.c
+# RUN: diff -u %S/Inputs/generated-funcs.c.no-generated.expected %t-no-generated.c
Index: clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.no-generated.expected
===================================================================
--- /dev/null
+++ clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.no-generated.expected
@@ -0,0 +1,100 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// Check that the CHECK lines are generated for clang-generated functions
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fopenmp %s -emit-llvm -o - | FileCheck --check-prefix=OMP %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu %s -emit-llvm -o - | FileCheck --check-prefix=NOOMP %s
+
+const int size = 1024 * 1024 * 32;
+
+double A[size];
+
+void foo(void);
+
+// OMP-LABEL: @main(
+// OMP-NEXT: entry:
+// OMP-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
+// OMP-NEXT: [[I:%.*]] = alloca i32, align 4
+// OMP-NEXT: store i32 0, i32* [[RETVAL]], align 4
+// OMP-NEXT: store i32 0, i32* [[I]], align 4
+// OMP-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @1, i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..1 to void (i32*, i32*, ...)*))
+// OMP-NEXT: call void @foo()
+// OMP-NEXT: ret i32 0
+//
+// NOOMP-LABEL: @main(
+// NOOMP-NEXT: entry:
+// NOOMP-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
+// NOOMP-NEXT: [[I:%.*]] = alloca i32, align 4
+// NOOMP-NEXT: store i32 0, i32* [[RETVAL]], align 4
+// NOOMP-NEXT: store i32 0, i32* [[I]], align 4
+// NOOMP-NEXT: store i32 0, i32* [[I]], align 4
+// NOOMP-NEXT: br label [[FOR_COND:%.*]]
+// NOOMP: for.cond:
+// NOOMP-NEXT: [[TMP0:%.*]] = load i32, i32* [[I]], align 4
+// NOOMP-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP0]], 33554432
+// NOOMP-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+// NOOMP: for.body:
+// NOOMP-NEXT: [[TMP1:%.*]] = load i32, i32* [[I]], align 4
+// NOOMP-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP1]] to i64
+// NOOMP-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [33554432 x double], [33554432 x double]* @A, i64 0, i64 [[IDXPROM]]
+// NOOMP-NEXT: store double 0.000000e+00, double* [[ARRAYIDX]], align 8
+// NOOMP-NEXT: br label [[FOR_INC:%.*]]
+// NOOMP: for.inc:
+// NOOMP-NEXT: [[TMP2:%.*]] = load i32, i32* [[I]], align 4
+// NOOMP-NEXT: [[INC:%.*]] = add nsw i32 [[TMP2]], 1
+// NOOMP-NEXT: store i32 [[INC]], i32* [[I]], align 4
+// NOOMP-NEXT: br label [[FOR_COND]]
+// NOOMP: for.end:
+// NOOMP-NEXT: call void @foo()
+// NOOMP-NEXT: ret i32 0
+//
+int main() {
+ int i = 0;
+
+#pragma omp parallel for
+ for (i = 0; i < size; ++i) {
+ A[i] = 0.0;
+ }
+
+ foo();
+
+ return 0;
+}
+
+// OMP-LABEL: @foo(
+// OMP-NEXT: entry:
+// OMP-NEXT: [[I:%.*]] = alloca i32, align 4
+// OMP-NEXT: store i32 0, i32* [[I]], align 4
+// OMP-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @1, i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*))
+// OMP-NEXT: ret void
+//
+// NOOMP-LABEL: @foo(
+// NOOMP-NEXT: entry:
+// NOOMP-NEXT: [[I:%.*]] = alloca i32, align 4
+// NOOMP-NEXT: store i32 0, i32* [[I]], align 4
+// NOOMP-NEXT: store i32 0, i32* [[I]], align 4
+// NOOMP-NEXT: br label [[FOR_COND:%.*]]
+// NOOMP: for.cond:
+// NOOMP-NEXT: [[TMP0:%.*]] = load i32, i32* [[I]], align 4
+// NOOMP-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP0]], 33554432
+// NOOMP-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+// NOOMP: for.body:
+// NOOMP-NEXT: [[TMP1:%.*]] = load i32, i32* [[I]], align 4
+// NOOMP-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP1]] to i64
+// NOOMP-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [33554432 x double], [33554432 x double]* @A, i64 0, i64 [[IDXPROM]]
+// NOOMP-NEXT: store double 1.000000e+00, double* [[ARRAYIDX]], align 8
+// NOOMP-NEXT: br label [[FOR_INC:%.*]]
+// NOOMP: for.inc:
+// NOOMP-NEXT: [[TMP2:%.*]] = load i32, i32* [[I]], align 4
+// NOOMP-NEXT: [[INC:%.*]] = add nsw i32 [[TMP2]], 1
+// NOOMP-NEXT: store i32 [[INC]], i32* [[I]], align 4
+// NOOMP-NEXT: br label [[FOR_COND]]
+// NOOMP: for.end:
+// NOOMP-NEXT: ret void
+//
+void foo(void) {
+ int i = 0;
+
+#pragma omp parallel for
+ for (i = 0; i < size; ++i) {
+ A[i] = 1.0;
+ }
+}
Index: clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.generated.expected
===================================================================
--- /dev/null
+++ clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.generated.expected
@@ -0,0 +1,229 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// Check that the CHECK lines are generated for clang-generated functions
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fopenmp %s -emit-llvm -o - | FileCheck --check-prefix=OMP %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu %s -emit-llvm -o - | FileCheck --check-prefix=NOOMP %s
+
+const int size = 1024 * 1024 * 32;
+
+double A[size];
+
+void foo(void);
+
+int main() {
+ int i = 0;
+
+#pragma omp parallel for
+ for (i = 0; i < size; ++i) {
+ A[i] = 0.0;
+ }
+
+ foo();
+
+ return 0;
+}
+
+void foo(void) {
+ int i = 0;
+
+#pragma omp parallel for
+ for (i = 0; i < size; ++i) {
+ A[i] = 1.0;
+ }
+}
+// OMP-LABEL: @foo(
+// OMP-NEXT: entry:
+// OMP-NEXT: [[I:%.*]] = alloca i32, align 4
+// OMP-NEXT: store i32 0, i32* [[I]], align 4
+// OMP-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @1, i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*))
+// OMP-NEXT: ret void
+//
+//
+// OMP-LABEL: @.omp_outlined.(
+// OMP-NEXT: entry:
+// OMP-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
+// OMP-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
+// OMP-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
+// OMP-NEXT: [[TMP:%.*]] = alloca i32, align 4
+// OMP-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
+// OMP-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
+// OMP-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
+// OMP-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// OMP-NEXT: [[I:%.*]] = alloca i32, align 4
+// OMP-NEXT: store i32* [[DOTGLOBAL_TID_:%.*]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// OMP-NEXT: store i32* [[DOTBOUND_TID_:%.*]], i32** [[DOTBOUND_TID__ADDR]], align 8
+// OMP-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4
+// OMP-NEXT: store i32 33554431, i32* [[DOTOMP_UB]], align 4
+// OMP-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4
+// OMP-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
+// OMP-NEXT: [[TMP0:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// OMP-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4
+// OMP-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* @0, i32 [[TMP1]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
+// OMP-NEXT: [[TMP2:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// OMP-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 33554431
+// OMP-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+// OMP: cond.true:
+// OMP-NEXT: br label [[COND_END:%.*]]
+// OMP: cond.false:
+// OMP-NEXT: [[TMP3:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// OMP-NEXT: br label [[COND_END]]
+// OMP: cond.end:
+// OMP-NEXT: [[COND:%.*]] = phi i32 [ 33554431, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ]
+// OMP-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
+// OMP-NEXT: [[TMP4:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
+// OMP-NEXT: store i32 [[TMP4]], i32* [[DOTOMP_IV]], align 4
+// OMP-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
+// OMP: omp.inner.for.cond:
+// OMP-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// OMP-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// OMP-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]]
+// OMP-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
+// OMP: omp.inner.for.body:
+// OMP-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// OMP-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP7]], 1
+// OMP-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]]
+// OMP-NEXT: store i32 [[ADD]], i32* [[I]], align 4
+// OMP-NEXT: [[TMP8:%.*]] = load i32, i32* [[I]], align 4
+// OMP-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP8]] to i64
+// OMP-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [33554432 x double], [33554432 x double]* @A, i64 0, i64 [[IDXPROM]]
+// OMP-NEXT: store double 1.000000e+00, double* [[ARRAYIDX]], align 8
+// OMP-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
+// OMP: omp.body.continue:
+// OMP-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
+// OMP: omp.inner.for.inc:
+// OMP-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// OMP-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP9]], 1
+// OMP-NEXT: store i32 [[ADD2]], i32* [[DOTOMP_IV]], align 4
+// OMP-NEXT: br label [[OMP_INNER_FOR_COND]]
+// OMP: omp.inner.for.end:
+// OMP-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
+// OMP: omp.loop.exit:
+// OMP-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @0, i32 [[TMP1]])
+// OMP-NEXT: ret void
+//
+//
+// OMP-LABEL: @main(
+// OMP-NEXT: entry:
+// OMP-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
+// OMP-NEXT: [[I:%.*]] = alloca i32, align 4
+// OMP-NEXT: store i32 0, i32* [[RETVAL]], align 4
+// OMP-NEXT: store i32 0, i32* [[I]], align 4
+// OMP-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @1, i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..1 to void (i32*, i32*, ...)*))
+// OMP-NEXT: call void @foo()
+// OMP-NEXT: ret i32 0
+//
+//
+// OMP-LABEL: @.omp_outlined..1(
+// OMP-NEXT: entry:
+// OMP-NEXT: [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
+// OMP-NEXT: [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
+// OMP-NEXT: [[DOTOMP_IV:%.*]] = alloca i32, align 4
+// OMP-NEXT: [[TMP:%.*]] = alloca i32, align 4
+// OMP-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
+// OMP-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
+// OMP-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
+// OMP-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
+// OMP-NEXT: [[I:%.*]] = alloca i32, align 4
+// OMP-NEXT: store i32* [[DOTGLOBAL_TID_:%.*]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// OMP-NEXT: store i32* [[DOTBOUND_TID_:%.*]], i32** [[DOTBOUND_TID__ADDR]], align 8
+// OMP-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4
+// OMP-NEXT: store i32 33554431, i32* [[DOTOMP_UB]], align 4
+// OMP-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4
+// OMP-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
+// OMP-NEXT: [[TMP0:%.*]] = load i32*, i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// OMP-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4
+// OMP-NEXT: call void @__kmpc_for_static_init_4(%struct.ident_t* @0, i32 [[TMP1]], i32 34, i32* [[DOTOMP_IS_LAST]], i32* [[DOTOMP_LB]], i32* [[DOTOMP_UB]], i32* [[DOTOMP_STRIDE]], i32 1, i32 1)
+// OMP-NEXT: [[TMP2:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// OMP-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP2]], 33554431
+// OMP-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+// OMP: cond.true:
+// OMP-NEXT: br label [[COND_END:%.*]]
+// OMP: cond.false:
+// OMP-NEXT: [[TMP3:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// OMP-NEXT: br label [[COND_END]]
+// OMP: cond.end:
+// OMP-NEXT: [[COND:%.*]] = phi i32 [ 33554431, [[COND_TRUE]] ], [ [[TMP3]], [[COND_FALSE]] ]
+// OMP-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
+// OMP-NEXT: [[TMP4:%.*]] = load i32, i32* [[DOTOMP_LB]], align 4
+// OMP-NEXT: store i32 [[TMP4]], i32* [[DOTOMP_IV]], align 4
+// OMP-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
+// OMP: omp.inner.for.cond:
+// OMP-NEXT: [[TMP5:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// OMP-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]], align 4
+// OMP-NEXT: [[CMP1:%.*]] = icmp sle i32 [[TMP5]], [[TMP6]]
+// OMP-NEXT: br i1 [[CMP1]], label [[OMP_INNER_FOR_BODY:%.*]], label [[OMP_INNER_FOR_END:%.*]]
+// OMP: omp.inner.for.body:
+// OMP-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// OMP-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP7]], 1
+// OMP-NEXT: [[ADD:%.*]] = add nsw i32 0, [[MUL]]
+// OMP-NEXT: store i32 [[ADD]], i32* [[I]], align 4
+// OMP-NEXT: [[TMP8:%.*]] = load i32, i32* [[I]], align 4
+// OMP-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP8]] to i64
+// OMP-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [33554432 x double], [33554432 x double]* @A, i64 0, i64 [[IDXPROM]]
+// OMP-NEXT: store double 0.000000e+00, double* [[ARRAYIDX]], align 8
+// OMP-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
+// OMP: omp.body.continue:
+// OMP-NEXT: br label [[OMP_INNER_FOR_INC:%.*]]
+// OMP: omp.inner.for.inc:
+// OMP-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_IV]], align 4
+// OMP-NEXT: [[ADD2:%.*]] = add nsw i32 [[TMP9]], 1
+// OMP-NEXT: store i32 [[ADD2]], i32* [[DOTOMP_IV]], align 4
+// OMP-NEXT: br label [[OMP_INNER_FOR_COND]]
+// OMP: omp.inner.for.end:
+// OMP-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
+// OMP: omp.loop.exit:
+// OMP-NEXT: call void @__kmpc_for_static_fini(%struct.ident_t* @0, i32 [[TMP1]])
+// OMP-NEXT: ret void
+//
+//
+// NOOMP-LABEL: @main(
+// NOOMP-NEXT: entry:
+// NOOMP-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
+// NOOMP-NEXT: [[I:%.*]] = alloca i32, align 4
+// NOOMP-NEXT: store i32 0, i32* [[RETVAL]], align 4
+// NOOMP-NEXT: store i32 0, i32* [[I]], align 4
+// NOOMP-NEXT: store i32 0, i32* [[I]], align 4
+// NOOMP-NEXT: br label [[FOR_COND:%.*]]
+// NOOMP: for.cond:
+// NOOMP-NEXT: [[TMP0:%.*]] = load i32, i32* [[I]], align 4
+// NOOMP-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP0]], 33554432
+// NOOMP-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+// NOOMP: for.body:
+// NOOMP-NEXT: [[TMP1:%.*]] = load i32, i32* [[I]], align 4
+// NOOMP-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP1]] to i64
+// NOOMP-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [33554432 x double], [33554432 x double]* @A, i64 0, i64 [[IDXPROM]]
+// NOOMP-NEXT: store double 0.000000e+00, double* [[ARRAYIDX]], align 8
+// NOOMP-NEXT: br label [[FOR_INC:%.*]]
+// NOOMP: for.inc:
+// NOOMP-NEXT: [[TMP2:%.*]] = load i32, i32* [[I]], align 4
+// NOOMP-NEXT: [[INC:%.*]] = add nsw i32 [[TMP2]], 1
+// NOOMP-NEXT: store i32 [[INC]], i32* [[I]], align 4
+// NOOMP-NEXT: br label [[FOR_COND]]
+// NOOMP: for.end:
+// NOOMP-NEXT: call void @foo()
+// NOOMP-NEXT: ret i32 0
+//
+//
+// NOOMP-LABEL: @foo(
+// NOOMP-NEXT: entry:
+// NOOMP-NEXT: [[I:%.*]] = alloca i32, align 4
+// NOOMP-NEXT: store i32 0, i32* [[I]], align 4
+// NOOMP-NEXT: store i32 0, i32* [[I]], align 4
+// NOOMP-NEXT: br label [[FOR_COND:%.*]]
+// NOOMP: for.cond:
+// NOOMP-NEXT: [[TMP0:%.*]] = load i32, i32* [[I]], align 4
+// NOOMP-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP0]], 33554432
+// NOOMP-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+// NOOMP: for.body:
+// NOOMP-NEXT: [[TMP1:%.*]] = load i32, i32* [[I]], align 4
+// NOOMP-NEXT: [[IDXPROM:%.*]] = sext i32 [[TMP1]] to i64
+// NOOMP-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [33554432 x double], [33554432 x double]* @A, i64 0, i64 [[IDXPROM]]
+// NOOMP-NEXT: store double 1.000000e+00, double* [[ARRAYIDX]], align 8
+// NOOMP-NEXT: br label [[FOR_INC:%.*]]
+// NOOMP: for.inc:
+// NOOMP-NEXT: [[TMP2:%.*]] = load i32, i32* [[I]], align 4
+// NOOMP-NEXT: [[INC:%.*]] = add nsw i32 [[TMP2]], 1
+// NOOMP-NEXT: store i32 [[INC]], i32* [[I]], align 4
+// NOOMP-NEXT: br label [[FOR_COND]]
+// NOOMP: for.end:
+// NOOMP-NEXT: ret void
+//
Index: clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c
===================================================================
--- /dev/null
+++ clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c
@@ -0,0 +1,31 @@
+// Check that the CHECK lines are generated for clang-generated functions
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fopenmp %s -emit-llvm -o - | FileCheck --check-prefix=OMP %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu %s -emit-llvm -o - | FileCheck --check-prefix=NOOMP %s
+
+const int size = 1024 * 1024 * 32;
+
+double A[size];
+
+void foo(void);
+
+int main() {
+ int i = 0;
+
+#pragma omp parallel for
+ for (i = 0; i < size; ++i) {
+ A[i] = 0.0;
+ }
+
+ foo();
+
+ return 0;
+}
+
+void foo(void) {
+ int i = 0;
+
+#pragma omp parallel for
+ for (i = 0; i < size; ++i) {
+ A[i] = 1.0;
+ }
+}
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits