[llvm] a26d303 - [UTC] Include return type/attributes under --version 2

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 2 01:01:55 PST 2023


Author: Nikita Popov
Date: 2023-03-02T09:59:22+01:00
New Revision: a26d3031cf89954d030e494d47ca6653d531dc82

URL: https://github.com/llvm/llvm-project/commit/a26d3031cf89954d030e494d47ca6653d531dc82
DIFF: https://github.com/llvm/llvm-project/commit/a26d3031cf89954d030e494d47ca6653d531dc82.diff

LOG: [UTC] Include return type/attributes under --version 2

If --function-signature is used with --version 2, then also include
the return type/attributes in the check lines. This is the
implementation of D133943 rebased on the --version mechanism from
D142473.

This doesn't bump the default version yet, because I'd like to do
that together with D140212 (which enables --function-signature by
default), as these changes seem closely related. For now this
functionality can be accessed by explicitly passing --version 2
to UTC.

Fixes https://github.com/llvm/llvm-project/issues/61058.

Differential Revision: https://reviews.llvm.org/D144963

Added: 
    clang/test/utils/update_cc_test_checks/Inputs/mangled_names.c.funcsig.v2.expected

Modified: 
    clang/test/utils/update_cc_test_checks/mangled_names.test
    llvm/utils/UpdateTestChecks/asm.py
    llvm/utils/UpdateTestChecks/common.py
    llvm/utils/UpdateTestChecks/isel.py
    llvm/utils/update_cc_test_checks.py
    llvm/utils/update_test_checks.py

Removed: 
    


################################################################################
diff  --git a/clang/test/utils/update_cc_test_checks/Inputs/mangled_names.c.funcsig.v2.expected b/clang/test/utils/update_cc_test_checks/Inputs/mangled_names.c.funcsig.v2.expected
new file mode 100644
index 0000000000000..c70179fc21777
--- /dev/null
+++ b/clang/test/utils/update_cc_test_checks/Inputs/mangled_names.c.funcsig.v2.expected
@@ -0,0 +1,43 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --version 2
+// Example input for update_cc_test_checks
+// RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+// CHECK-LABEL: define dso_local i64 @test
+// CHECK-SAME: (i64 noundef [[A:%.*]], i32 noundef [[B:%.*]]) #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[A_ADDR:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i64 [[A]], ptr [[A_ADDR]], align 8
+// CHECK-NEXT:    store i32 [[B]], ptr [[B_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr [[A_ADDR]], align 8
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
+// CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[TMP1]] to i64
+// CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[TMP0]], [[CONV]]
+// CHECK-NEXT:    ret i64 [[ADD]]
+//
+long test(long a, int b) {
+  return a + b;
+}
+
+// A function with a mangled name
+// CHECK-LABEL: define dso_local i64 @_Z4testlii
+// CHECK-SAME: (i64 noundef [[A:%.*]], i32 noundef [[B:%.*]], i32 noundef [[C:%.*]]) #[[ATTR0]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[A_ADDR:%.*]] = alloca i64, align 8
+// CHECK-NEXT:    [[B_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[C_ADDR:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i64 [[A]], ptr [[A_ADDR]], align 8
+// CHECK-NEXT:    store i32 [[B]], ptr [[B_ADDR]], align 4
+// CHECK-NEXT:    store i32 [[C]], ptr [[C_ADDR]], align 4
+// CHECK-NEXT:    [[TMP0:%.*]] = load i64, ptr [[A_ADDR]], align 8
+// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4
+// CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[TMP1]] to i64
+// CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[TMP0]], [[CONV]]
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[C_ADDR]], align 4
+// CHECK-NEXT:    [[CONV1:%.*]] = sext i32 [[TMP2]] to i64
+// CHECK-NEXT:    [[ADD2:%.*]] = add nsw i64 [[ADD]], [[CONV1]]
+// CHECK-NEXT:    ret i64 [[ADD2]]
+//
+__attribute__((overloadable)) long test(long a, int b, int c) {
+  return a + b + c;
+}

diff  --git a/clang/test/utils/update_cc_test_checks/mangled_names.test b/clang/test/utils/update_cc_test_checks/mangled_names.test
index bc88c9b5a382f..40f8a5d78b521 100644
--- a/clang/test/utils/update_cc_test_checks/mangled_names.test
+++ b/clang/test/utils/update_cc_test_checks/mangled_names.test
@@ -16,3 +16,6 @@
 # RUN: grep -v UTC_ARGS %t.c > %t-no-args.c
 # RUN: %update_cc_test_checks %t-no-args.c
 # RUN: 
diff  -u %t-no-args.c %S/Inputs/mangled_names.c.expected
+## Also try --version 2
+# RUN: %update_cc_test_checks %t.c --function-signature --version 2
+# RUN: 
diff  -u %t.c %S/Inputs/mangled_names.c.funcsig.v2.expected

diff  --git a/llvm/utils/UpdateTestChecks/asm.py b/llvm/utils/UpdateTestChecks/asm.py
index e24197f3b63bb..697d3ee17d96f 100644
--- a/llvm/utils/UpdateTestChecks/asm.py
+++ b/llvm/utils/UpdateTestChecks/asm.py
@@ -534,7 +534,7 @@ def get_run_handler(triple):
 def add_checks(output_lines, comment_marker, prefix_list, func_dict,
                func_name, global_vars_seen_dict, is_filtered):
   # Label format is based on ASM string.
-  check_label_format = '{} %s-LABEL: %s%s%s'.format(comment_marker)
+  check_label_format = '{} %s-LABEL: %s%s%s%s'.format(comment_marker)
   return common.add_checks(output_lines, comment_marker, prefix_list, func_dict,
-                           func_name, check_label_format, True, False,
+                           func_name, check_label_format, True, False, 1,
                            global_vars_seen_dict, is_filtered=is_filtered)

diff  --git a/llvm/utils/UpdateTestChecks/common.py b/llvm/utils/UpdateTestChecks/common.py
index b35fac4c4817a..b52306a1c67f9 100644
--- a/llvm/utils/UpdateTestChecks/common.py
+++ b/llvm/utils/UpdateTestChecks/common.py
@@ -22,6 +22,7 @@
 Version changelog:
 
 1: Initial version, used by tests that don't specify --version explicitly.
+2: --function-signature now also checks return type/attributes.
 """
 DEFAULT_VERSION = 1
 
@@ -346,7 +347,7 @@ def invoke_tool(exe, cmd_args, ir, preprocess_cmd=None, verbose=False):
 UNUSED_NOTE = 'NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:'
 
 OPT_FUNCTION_RE = re.compile(
-    r'^(\s*;\s*Function\sAttrs:\s(?P<attrs>[\w\s():,]+?))?\s*define\s+(?:internal\s+)?[^@]*@(?P<func>[\w.$-]+?)\s*'
+    r'^(\s*;\s*Function\sAttrs:\s(?P<attrs>[\w\s():,]+?))?\s*define\s+(?P<funcdef_attrs_and_ret>[^@]*)@(?P<func>[\w.$-]+?)\s*'
     r'(?P<args_and_sig>\((\)|(.*?[\w.-]+?)\))[^{]*\{)\n(?P<body>.*?)^\}$',
     flags=(re.M | re.S))
 
@@ -459,13 +460,14 @@ def do_scrub(body, scrubber, scrubber_args, extra):
 
 # Build up a dictionary of all the function bodies.
 class function_body(object):
-  def __init__(self, string, extra, args_and_sig, attrs, func_name_separator):
+  def __init__(self, string, extra, funcdef_attrs_and_ret, args_and_sig, attrs, func_name_separator):
     self.scrub = string
     self.extrascrub = extra
+    self.funcdef_attrs_and_ret = funcdef_attrs_and_ret
     self.args_and_sig = args_and_sig
     self.attrs = attrs
     self.func_name_separator = func_name_separator
-  def is_same_except_arg_names(self, extrascrub, args_and_sig, attrs, is_backend):
+  def is_same_except_arg_names(self, extrascrub, funcdef_attrs_and_ret, args_and_sig, attrs, is_backend):
     arg_names = set()
     def drop_arg_names(match):
       arg_names.add(match.group(variable_group_in_ir_value_match))
@@ -478,6 +480,8 @@ def repl_arg_names(match):
       if match.group(variable_group_in_ir_value_match) is not None and match.group(variable_group_in_ir_value_match) in arg_names:
         return match.group(1) + match.group(match.lastindex)
       return match.group(1) + match.group(2) + match.group(match.lastindex)
+    if self.funcdef_attrs_and_ret != funcdef_attrs_and_ret:
+      return False
     if self.attrs != attrs:
       return False
     ans0 = IR_VALUE_RE.sub(drop_arg_names, self.args_and_sig)
@@ -553,6 +557,7 @@ def process_run_line(self, function_re, scrubber, raw_tool_output, prefixes, is_
       else:
         func_name_separator = ''
       attrs = m.group('attrs') if self._check_attributes else ''
+      funcdef_attrs_and_ret = m.group('funcdef_attrs_and_ret') if self._record_args else ''
       # Determine if we print arguments, the opening brace, or nothing after the
       # function name
       if self._record_args and 'args_and_sig' in m.groupdict():
@@ -607,9 +612,11 @@ def process_run_line(self, function_re, scrubber, raw_tool_output, prefixes, is_
           if (self._func_dict[prefix][func] is not None and
               (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)):
+               self._func_dict[prefix][func].attrs != attrs or
+               self._func_dict[prefix][func].funcdef_attrs_and_ret != funcdef_attrs_and_ret)):
             if self._func_dict[prefix][func].is_same_except_arg_names(
                 scrubbed_extra,
+                funcdef_attrs_and_ret,
                 args_and_sig,
                 attrs,
                 is_backend):
@@ -624,8 +631,8 @@ def process_run_line(self, function_re, scrubber, raw_tool_output, prefixes, is_
         else:
           if prefix not in self._processed_prefixes:
             self._func_dict[prefix][func] = function_body(
-                scrubbed_body, scrubbed_extra, args_and_sig, attrs,
-                func_name_separator)
+                scrubbed_body, scrubbed_extra, funcdef_attrs_and_ret,
+                args_and_sig, attrs, func_name_separator)
             self._func_order[prefix].append(func)
           else:
             # An earlier RUN line used this check prefixes but didn't produce
@@ -897,7 +904,7 @@ def generalize_asm_check_lines(lines, vars_seen, global_vars_seen):
                                        global_vars_seen, asm_nameless_values,
                                        ASM_VALUE_RE, True)
 
-def add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name, check_label_format, is_backend, is_analyze, global_vars_seen_dict, is_filtered):
+def add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name, check_label_format, is_backend, is_analyze, version, global_vars_seen_dict, is_filtered):
   # prefix_exclusions are prefixes we cannot use to print the function because it doesn't exist in run lines that use these prefixes as well.
   prefix_exclusions = set()
   printed_prefixes = []
@@ -945,6 +952,11 @@ def add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name,
       printed_prefixes.append(checkprefix)
       attrs = str(func_dict[checkprefix][func_name].attrs)
       attrs = '' if attrs == 'None' else attrs
+      if version > 1:
+        funcdef_attrs_and_ret = func_dict[checkprefix][func_name].funcdef_attrs_and_ret
+      else:
+        funcdef_attrs_and_ret = ''
+
       if attrs:
         output_lines.append('%s %s: Function Attrs: %s' % (comment_marker, checkprefix, attrs))
       args_and_sig = str(func_dict[checkprefix][func_name].args_and_sig)
@@ -952,10 +964,10 @@ def add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name,
         args_and_sig = generalize_check_lines([args_and_sig], is_analyze, vars_seen, global_vars_seen)[0]
       func_name_separator = func_dict[checkprefix][func_name].func_name_separator
       if '[[' in args_and_sig:
-        output_lines.append(check_label_format % (checkprefix, func_name, '', func_name_separator))
+        output_lines.append(check_label_format % (checkprefix, funcdef_attrs_and_ret, func_name, '', func_name_separator))
         output_lines.append('%s %s-SAME: %s' % (comment_marker, checkprefix, args_and_sig))
       else:
-        output_lines.append(check_label_format % (checkprefix, func_name, args_and_sig, func_name_separator))
+        output_lines.append(check_label_format % (checkprefix, funcdef_attrs_and_ret, func_name, args_and_sig, func_name_separator))
       func_body = str(func_dict[checkprefix][func_name]).splitlines()
       if not func_body:
         # We have filtered everything.
@@ -1031,20 +1043,26 @@ def add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name,
   return printed_prefixes
 
 def add_ir_checks(output_lines, comment_marker, prefix_list, func_dict,
-                  func_name, preserve_names, function_sig,
+                  func_name, preserve_names, function_sig, version,
                   global_vars_seen_dict, is_filtered):
   # Label format is based on IR string.
-  function_def_regex = 'define {{[^@]+}}' if function_sig else ''
+  if function_sig and version > 1:
+    function_def_regex = 'define %s'
+  elif function_sig:
+    function_def_regex = 'define {{[^@]+}}%s'
+  else:
+    function_def_regex = '%s'
   check_label_format = '{} %s-LABEL: {}@%s%s%s'.format(comment_marker, function_def_regex)
   return add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name,
-                    check_label_format, False, preserve_names, global_vars_seen_dict,
+                    check_label_format, False, preserve_names, version,
+                    global_vars_seen_dict,
                     is_filtered)
 
 def add_analyze_checks(output_lines, comment_marker, prefix_list, func_dict, func_name, is_filtered):
-  check_label_format = '{} %s-LABEL: \'%s%s%s\''.format(comment_marker)
+  check_label_format = '{} %s-LABEL: \'%s%s%s%s\''.format(comment_marker)
   global_vars_seen_dict = {}
   return add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name,
-                    check_label_format, False, True, global_vars_seen_dict,
+                    check_label_format, False, True, 1, global_vars_seen_dict,
                     is_filtered)
 
 def build_global_values_dictionary(glob_val_dict, raw_tool_output, prefixes):

diff  --git a/llvm/utils/UpdateTestChecks/isel.py b/llvm/utils/UpdateTestChecks/isel.py
index 2978e5133ecbc..c10a55540efdd 100644
--- a/llvm/utils/UpdateTestChecks/isel.py
+++ b/llvm/utils/UpdateTestChecks/isel.py
@@ -51,7 +51,7 @@ def get_run_handler(triple):
 def add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name,
                global_vars_seen_dict, is_filtered):
   # Label format is based on iSel string.
-  check_label_format = '{} %s-LABEL: %s%s%s'.format(comment_marker)
+  check_label_format = '{} %s-LABEL: %s%s%s%s'.format(comment_marker)
   return common.add_checks(output_lines, comment_marker, prefix_list, func_dict,
-                           func_name, check_label_format, True, False,
+                           func_name, check_label_format, True, False, 1,
                            global_vars_seen_dict, is_filtered=is_filtered)

diff  --git a/llvm/utils/update_cc_test_checks.py b/llvm/utils/update_cc_test_checks.py
index 5b6ce0d629e4a..0861fe8c18948 100755
--- a/llvm/utils/update_cc_test_checks.py
+++ b/llvm/utils/update_cc_test_checks.py
@@ -350,6 +350,7 @@ def check_generator(my_output_lines, prefixes, func):
                                       prefixes,
                                       func_dict, func, False,
                                       ti.args.function_signature,
+                                      ti.args.version,
                                       global_vars_seen_dict,
                                       is_filtered=builder.is_filtered())
         else:
@@ -417,6 +418,7 @@ def check_generator(my_output_lines, prefixes, func):
                       mangled,
                       False,
                       args.function_signature,
+                      args.version,
                       global_vars_seen_dict,
                       is_filtered=builder.is_filtered()))
               if line.rstrip('\n') == '//':

diff  --git a/llvm/utils/update_test_checks.py b/llvm/utils/update_test_checks.py
index 2a5ecc67ed1e5..a977abbfd3e6b 100755
--- a/llvm/utils/update_test_checks.py
+++ b/llvm/utils/update_test_checks.py
@@ -177,6 +177,7 @@ def main():
                   func,
                   False,
                   args.function_signature,
+                  args.version,
                   global_vars_seen_dict,
                   is_filtered=builder.is_filtered())))
     else:
@@ -203,6 +204,7 @@ def main():
                   func_name,
                   args.preserve_names,
                   args.function_signature,
+                  args.version,
                   global_vars_seen_dict,
                   is_filtered=builder.is_filtered()))
           is_in_function_start = False


        


More information about the llvm-commits mailing list