jdoerfert updated this revision to Diff 346030.
jdoerfert marked 4 inline comments as done.
jdoerfert added a comment.

Skip duplicates in the line2spell_and_mangled_list as that causes functions to 
be missed.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D102558/new/

https://reviews.llvm.org/D102558

Files:
  clang/test/utils/update_cc_test_checks/Inputs/generated-funcs-regex.c.expected
  
clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.generated.expected
  clang/test/utils/update_cc_test_checks/Inputs/lots-of-generated-funcs.c
  
clang/test/utils/update_cc_test_checks/Inputs/lots-of-generated-funcs.c.lots-of-generated.expected
  
clang/test/utils/update_cc_test_checks/Inputs/lots-of-generated-funcs.c.no-lots-of-generated.expected
  clang/test/utils/update_cc_test_checks/lots-of-generated-funcs.test
  llvm/utils/UpdateTestChecks/common.py
  llvm/utils/update_cc_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
@@ -138,6 +138,9 @@
                                                       '--include-generated-funcs',
                                                       True)
 
+    # TODO: use common.get_total_function_order to avoid adding new functions at the end but
+    #       instead place them in order between existing ones. See the CC script.
+
     if 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
Index: llvm/utils/update_cc_test_checks.py
===================================================================
--- llvm/utils/update_cc_test_checks.py
+++ llvm/utils/update_cc_test_checks.py
@@ -305,8 +305,9 @@
                                                       lambda args: ti.args.include_generated_funcs,
                                                       '--include-generated-funcs',
                                                       True)
+    total_function_order = common.get_total_function_order(filecheck_run_list, builder.func_order())
 
-    if include_generated_funcs:
+    if include_generated_funcs and not total_function_order:
       # 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.
@@ -337,6 +338,62 @@
                                check_generator(my_output_lines,
                                                prefixes, func))
     else:
+      trailing_functions = []
+      # If we might have generated functions we need to place them in the right position now,
+      # trailing ones are kept separate though.
+      if include_generated_funcs:
+        seen_mangled = set()
+        total_order_idx = 0
+        for line in line2spell_and_mangled_list.keys():
+          to_be_added = []
+          for spell, mangled in line2spell_and_mangled_list[line]:
+            if mangled not in total_function_order or mangled in seen_mangled:
+              continue
+            seen_mangled.add(mangled)
+
+            # Figure out where this existing function is in the total order. All functions we
+            # skipped are inserted before this one.
+            index = total_function_order.index(mangled)
+            while total_order_idx < index:
+              to_be_added.append(total_function_order[total_order_idx])
+              total_order_idx += 1
+            # Account for the function itself (spell, mangled)
+            total_order_idx += 1
+          # Reverse the order to match total order again before we insert the functions
+          # in the current line.
+          to_be_added.reverse()
+          for tba in to_be_added:
+            line2spell_and_mangled_list[line].insert(0, ('', tba))
+
+        # All functions we have not handled yet are added to the end.
+        while total_order_idx < len(total_function_order):
+          func = total_function_order[total_order_idx]
+          trailing_functions.append(func)
+          total_order_idx += 1
+
+      def handle_functions_on_line(output_lines, line, args, spell, mangled, added, include_line):
+        # 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 and spell not in line):
+          return
+        if args.functions is None or any(re.search(regex, spell) for regex in args.functions):
+          last_line = output_lines[-1].strip()
+          while last_line == '//':
+            # Remove the comment line since we will generate a new  comment
+            # line as part of common.add_ir_checks()
+            output_lines.pop()
+            last_line = output_lines[-1].strip()
+          if added:
+            output_lines.append('//')
+          added.add(mangled)
+          common.add_ir_checks(output_lines, '//', filecheck_run_list, func_dict, mangled,
+                               False, args.function_signature, global_vars_seen_dict)
+          if line.rstrip('\n') == '//':
+            include_line = False
+
       # Normal mode.  Put checks before each source function.
       for line_info in ti.iterlines(output_lines):
         idx = line_info.line_number
@@ -349,31 +406,17 @@
         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):
-              last_line = output_lines[-1].strip()
-              while last_line == '//':
-                # Remove the comment line since we will generate a new  comment
-                # line as part of common.add_ir_checks()
-                output_lines.pop()
-                last_line = output_lines[-1].strip()
-              if added:
-                output_lines.append('//')
-              added.add(mangled)
-              common.add_ir_checks(output_lines, '//', filecheck_run_list, func_dict, mangled,
-                                   False, args.function_signature, global_vars_seen_dict)
-              if line.rstrip('\n') == '//':
-                include_line = False
+            handle_functions_on_line(output_lines, line, args, spell, mangled, added, include_line)
 
         if include_line:
           output_lines.append(line.rstrip('\n'))
 
+      # After we inserted check lines in the original program we append all check lines for functions
+      # that were generated after the existing ones.
+      added = set()
+      for func in trailing_functions:
+          handle_functions_on_line(output_lines, func, args, func, func, added, include_line)
+
     common.debug('Writing %d lines to %s...' % (len(output_lines), ti.path))
     with open(ti.path, '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
@@ -290,6 +290,24 @@
   def __str__(self):
     return self.scrub
 
+# Try to put all functions into a total order, this might not work if two run
+# lines generated the functions in a different order.
+def get_total_function_order(prefix_list, func_order):
+  total_order = []
+  for prefix_item in prefix_list:
+    prefixes = prefix_item[0]
+    for prefix in prefixes:
+        for func in func_order[prefix]:
+            total_idx = 0
+            if func in total_order:
+                idx = total_order.index(func)
+                if idx < total_idx:
+                    return None
+                total_idx = idx + 1
+            else:
+                total_order.append(func)
+  return total_order
+
 class FunctionTestBuilder:
   def __init__(self, run_list, flags, scrubber_args):
     self._verbose = flags.verbose
@@ -349,28 +367,8 @@
         print('Processing function: ' + func, file=sys.stderr)
         for l in scrubbed_body.splitlines():
           print('  ' + l, file=sys.stderr)
-      for prefix in prefixes:
-        if func in self._func_dict[prefix]:
-          if (self._func_dict[prefix][func] is None or
-              str(self._func_dict[prefix][func]) != scrubbed_body or
-              self._func_dict[prefix][func].args_and_sig != args_and_sig or
-                  self._func_dict[prefix][func].attrs != attrs):
-            if (self._func_dict[prefix][func] is not None and
-                self._func_dict[prefix][func].is_same_except_arg_names(
-                scrubbed_extra,
-                args_and_sig,
-                attrs)):
-              self._func_dict[prefix][func].scrub = scrubbed_extra
-              self._func_dict[prefix][func].args_and_sig = args_and_sig
-              continue
-            else:
-              # This means a previous RUN line produced a body for this function
-              # that is different from the one produced by this current RUN line,
-              # so the body can't be common accross RUN lines. We use None to
-              # indicate that.
-              self._func_dict[prefix][func] = None
-              continue
 
+      for prefix in prefixes:
         # Replace function names matching the regex.
         for regex in self._replace_value_regex:
           # Pattern that matches capture groups in the regex in leftmost order.
@@ -395,6 +393,27 @@
             # capture groups set.
             scrubbed_body = re.sub(func_repl, '{{' + func_repl + '}}', scrubbed_body)
 
+        if func in self._func_dict[prefix]:
+          if (self._func_dict[prefix][func] is None or
+              str(self._func_dict[prefix][func]) != scrubbed_body or
+              self._func_dict[prefix][func].args_and_sig != args_and_sig or
+                  self._func_dict[prefix][func].attrs != attrs):
+            if (self._func_dict[prefix][func] is not None and
+                self._func_dict[prefix][func].is_same_except_arg_names(
+                scrubbed_extra,
+                args_and_sig,
+                attrs)):
+              self._func_dict[prefix][func].scrub = scrubbed_extra
+              self._func_dict[prefix][func].args_and_sig = args_and_sig
+              continue
+            else:
+              # This means a previous RUN line produced a body for this function
+              # that is different from the one produced by this current RUN line,
+              # so the body can't be common across RUN lines. We use None to
+              # indicate that.
+              self._func_dict[prefix][func] = None
+              continue
+
         self._func_dict[prefix][func] = function_body(
             scrubbed_body, scrubbed_extra, args_and_sig, attrs)
         self._func_order[prefix].append(func)
Index: clang/test/utils/update_cc_test_checks/lots-of-generated-funcs.test
===================================================================
--- /dev/null
+++ clang/test/utils/update_cc_test_checks/lots-of-generated-funcs.test
@@ -0,0 +1,12 @@
+## Test that CHECK lines are generated for clang-generated functions
+
+# RUN: cp %S/Inputs/lots-of-generated-funcs.c %t-lots-of-generated.c && %update_cc_test_checks --include-generated-funcs %t-lots-of-generated.c
+# RUN: diff -u %S/Inputs/lots-of-generated-funcs.c.lots-of-generated.expected %t-lots-of-generated.c
+# RUN: cp %S/Inputs/lots-of-generated-funcs.c %t-no-lots-of-generated.c && %update_cc_test_checks %t-no-lots-of-generated.c
+# RUN: diff -u %S/Inputs/lots-of-generated-funcs.c.no-lots-of-generated.expected %t-no-lots-of-generated.c
+
+## Check that re-running update_cc_test_checks doesn't change the output
+# RUN: %update_cc_test_checks --include-generated-funcs %t-lots-of-generated.c
+# RUN: diff -u %S/Inputs/lots-of-generated-funcs.c.lots-of-generated.expected %t-lots-of-generated.c
+# RUN: %update_cc_test_checks %t-no-lots-of-generated.c
+# RUN: diff -u %S/Inputs/lots-of-generated-funcs.c.no-lots-of-generated.expected %t-no-lots-of-generated.c
Index: clang/test/utils/update_cc_test_checks/Inputs/lots-of-generated-funcs.c.no-lots-of-generated.expected
===================================================================
--- /dev/null
+++ clang/test/utils/update_cc_test_checks/Inputs/lots-of-generated-funcs.c.no-lots-of-generated.expected
@@ -0,0 +1,73 @@
+// 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
+
+// OMP-LABEL: @t0(
+// OMP-NEXT:  entry:
+// OMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1:[0-9]+]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*))
+// OMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..1 to void (i32*, i32*, ...)*))
+// OMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..2 to void (i32*, i32*, ...)*))
+// OMP-NEXT:    ret void
+//
+// NOOMP-LABEL: @t0(
+// NOOMP-NEXT:  entry:
+// NOOMP-NEXT:    ret void
+//
+void t0() {
+  #pragma omp parallel
+  {
+  }
+  #pragma omp parallel
+  {
+  }
+  #pragma omp parallel
+  {
+  }
+}
+
+// OMP-LABEL: @t1(
+// OMP-NEXT:  entry:
+// OMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..3 to void (i32*, i32*, ...)*))
+// OMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..4 to void (i32*, i32*, ...)*))
+// OMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..5 to void (i32*, i32*, ...)*))
+// OMP-NEXT:    ret void
+//
+// NOOMP-LABEL: @t1(
+// NOOMP-NEXT:  entry:
+// NOOMP-NEXT:    ret void
+//
+void t1() {
+  #pragma omp parallel
+  {
+  }
+  #pragma omp parallel
+  {
+  }
+  #pragma omp parallel
+  {
+  }
+}
+
+// OMP-LABEL: @t2(
+// OMP-NEXT:  entry:
+// OMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..6 to void (i32*, i32*, ...)*))
+// OMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..7 to void (i32*, i32*, ...)*))
+// OMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..8 to void (i32*, i32*, ...)*))
+// OMP-NEXT:    ret void
+//
+// NOOMP-LABEL: @t2(
+// NOOMP-NEXT:  entry:
+// NOOMP-NEXT:    ret void
+//
+void t2() {
+  #pragma omp parallel
+  {
+  }
+  #pragma omp parallel
+  {
+  }
+  #pragma omp parallel
+  {
+  }
+}
Index: clang/test/utils/update_cc_test_checks/Inputs/lots-of-generated-funcs.c.lots-of-generated.expected
===================================================================
--- /dev/null
+++ clang/test/utils/update_cc_test_checks/Inputs/lots-of-generated-funcs.c.lots-of-generated.expected
@@ -0,0 +1,145 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --include-generated-funcs
+// 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
+
+// OMP-LABEL: @t0(
+// OMP-NEXT:  entry:
+// OMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1:[0-9]+]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*))
+// OMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..1 to void (i32*, i32*, ...)*))
+// OMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..2 to void (i32*, i32*, ...)*))
+// OMP-NEXT:    ret void
+//
+// NOOMP-LABEL: @t0(
+// NOOMP-NEXT:  entry:
+// NOOMP-NEXT:    ret void
+//
+void t0() {
+  #pragma omp parallel
+  {
+  }
+  #pragma omp parallel
+  {
+  }
+  #pragma omp parallel
+  {
+  }
+}
+
+// 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:    store i32* [[DOTGLOBAL_TID_:%.*]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// OMP-NEXT:    store i32* [[DOTBOUND_TID_:%.*]], i32** [[DOTBOUND_TID__ADDR]], align 8
+// OMP-NEXT:    ret void
+//
+// 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:    store i32* [[DOTGLOBAL_TID_:%.*]], i32** [[DOTGLOBAL_TID__ADDR]], align 8
+// OMP-NEXT:    store i32* [[DOTBOUND_TID_:%.*]], i32** [[DOTBOUND_TID__ADDR]], align 8
+// OMP-NEXT:    ret void
+//
+// OMP-LABEL: @.omp_outlined..2(
+// OMP-NEXT:  entry:
+// OMP-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
+// OMP-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
+// 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:    ret void
+//
+// OMP-LABEL: @t1(
+// OMP-NEXT:  entry:
+// OMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..3 to void (i32*, i32*, ...)*))
+// OMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..4 to void (i32*, i32*, ...)*))
+// OMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..5 to void (i32*, i32*, ...)*))
+// OMP-NEXT:    ret void
+//
+// NOOMP-LABEL: @t1(
+// NOOMP-NEXT:  entry:
+// NOOMP-NEXT:    ret void
+//
+void t1() {
+  #pragma omp parallel
+  {
+  }
+  #pragma omp parallel
+  {
+  }
+  #pragma omp parallel
+  {
+  }
+}
+
+// OMP-LABEL: @.omp_outlined..3(
+// OMP-NEXT:  entry:
+// OMP-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
+// OMP-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
+// 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:    ret void
+//
+// OMP-LABEL: @.omp_outlined..4(
+// OMP-NEXT:  entry:
+// OMP-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
+// OMP-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
+// 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:    ret void
+//
+// OMP-LABEL: @.omp_outlined..5(
+// OMP-NEXT:  entry:
+// OMP-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
+// OMP-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
+// 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:    ret void
+//
+// OMP-LABEL: @t2(
+// OMP-NEXT:  entry:
+// OMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..6 to void (i32*, i32*, ...)*))
+// OMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..7 to void (i32*, i32*, ...)*))
+// OMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB1]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..8 to void (i32*, i32*, ...)*))
+// OMP-NEXT:    ret void
+//
+// NOOMP-LABEL: @t2(
+// NOOMP-NEXT:  entry:
+// NOOMP-NEXT:    ret void
+//
+void t2() {
+  #pragma omp parallel
+  {
+  }
+  #pragma omp parallel
+  {
+  }
+  #pragma omp parallel
+  {
+  }
+}
+// OMP-LABEL: @.omp_outlined..6(
+// OMP-NEXT:  entry:
+// OMP-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
+// OMP-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
+// 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:    ret void
+//
+// OMP-LABEL: @.omp_outlined..7(
+// OMP-NEXT:  entry:
+// OMP-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
+// OMP-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
+// 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:    ret void
+//
+// OMP-LABEL: @.omp_outlined..8(
+// OMP-NEXT:  entry:
+// OMP-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
+// OMP-NEXT:    [[DOTBOUND_TID__ADDR:%.*]] = alloca i32*, align 8
+// 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:    ret void
+//
Index: clang/test/utils/update_cc_test_checks/Inputs/lots-of-generated-funcs.c
===================================================================
--- /dev/null
+++ clang/test/utils/update_cc_test_checks/Inputs/lots-of-generated-funcs.c
@@ -0,0 +1,39 @@
+// 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
+
+void t0() {
+  #pragma omp parallel
+  {
+  }
+  #pragma omp parallel
+  {
+  }
+  #pragma omp parallel
+  {
+  }
+}
+
+void t1() {
+  #pragma omp parallel
+  {
+  }
+  #pragma omp parallel
+  {
+  }
+  #pragma omp parallel
+  {
+  }
+}
+
+void t2() {
+  #pragma omp parallel
+  {
+  }
+  #pragma omp parallel
+  {
+  }
+  #pragma omp parallel
+  {
+  }
+}
Index: clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.generated.expected
===================================================================
--- clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.generated.expected
+++ clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.generated.expected
@@ -9,6 +9,43 @@
 
 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* @[[GLOB2:[0-9]+]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined. 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]], !llvm.loop [[LOOP2:![0-9]+]]
+// NOOMP:       for.end:
+// NOOMP-NEXT:    call void @foo()
+// NOOMP-NEXT:    ret i32 0
+//
 int main() {
   int i = 0;
 
@@ -22,25 +59,6 @@
   return 0;
 }
 
-void foo(void) {
-  int i = 0;
-
-#pragma omp parallel for
-  for (i = 0; i < size; ++i) {
-    A[i] = 1.0;
-  }
-}
-// 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* @[[GLOB2:[0-9]+]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*))
-// OMP-NEXT:    call void @foo()
-// OMP-NEXT:    ret i32 0
-//
-//
 // OMP-LABEL: @.omp_outlined.(
 // OMP-NEXT:  entry:
 // OMP-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
@@ -103,7 +121,6 @@
 // OMP-NEXT:    call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], i32 [[TMP1]])
 // OMP-NEXT:    ret void
 //
-//
 // OMP-LABEL: @foo(
 // OMP-NEXT:  entry:
 // OMP-NEXT:    [[I:%.*]] = alloca i32, align 4
@@ -111,7 +128,38 @@
 // OMP-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @[[GLOB2]], i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* @.omp_outlined..1 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]], !llvm.loop [[LOOP4:![0-9]+]]
+// 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;
+  }
+}
 // OMP-LABEL: @.omp_outlined..1(
 // OMP-NEXT:  entry:
 // OMP-NEXT:    [[DOTGLOBAL_TID__ADDR:%.*]] = alloca i32*, align 8
@@ -174,56 +222,3 @@
 // OMP-NEXT:    call void @__kmpc_for_static_fini(%struct.ident_t* @[[GLOB1]], 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]], !llvm.loop [[LOOP2:![0-9]+]]
-// 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]], !llvm.loop [[LOOP4:![0-9]+]]
-// NOOMP:       for.end:
-// NOOMP-NEXT:    ret void
-//
Index: clang/test/utils/update_cc_test_checks/Inputs/generated-funcs-regex.c.expected
===================================================================
--- clang/test/utils/update_cc_test_checks/Inputs/generated-funcs-regex.c.expected
+++ clang/test/utils/update_cc_test_checks/Inputs/generated-funcs-regex.c.expected
@@ -4,14 +4,6 @@
 void __test_offloading_42_abcdef_bar_l123();
 void use(int);
 
-void foo(int a)
-{
-    #pragma omp target
-        use(a);
-
-    __test_offloading_42_abcdef_bar_l123();
-    int somevar_abc123_;
-}
 // CHECK-LABEL: @foo(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4
@@ -26,7 +18,14 @@
 // CHECK-NEXT:    call void (...) @{{__test_offloading_[a-z0-9]+_[a-z0-9]+_bar_l[0-9]+}}()
 // CHECK-NEXT:    ret void
 //
-//
+void foo(int a)
+{
+    #pragma omp target
+        use(a);
+
+    __test_offloading_42_abcdef_bar_l123();
+    int somevar_abc123_;
+}
 // CHECK-LABEL: @{{__omp_offloading_[a-z0-9]+_[a-z0-9]+_foo_l[0-9]+}}(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    [[A_ADDR:%.*]] = alloca i64, align 8
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to