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
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to