Skip to content

Commit 1ce846b

Browse files
committed
Replace func name with regex for update test scripts
The patch adds an argument to update test scripts, such as update_cc_test_checks, for replacing a function name matching a regex. This functionality is needed to match generated function signatures that include file hashes. Example: The function signature for the following function: `__omp_offloading_50_b84c41e__Z9ftemplateIiET_i_l30_worker` with `--replace-function-regex "__omp_offloading_[0-9]+_[a-z0-9]+_(.*)"` will become: `CHECK-LABEL: @{{__omp_offloading_[0-9]+_[a-z0-9]+__Z9ftemplateIiET_i_l30_worker}}(` Reviewed By: jdoerfert Differential Revision: https://reviews.llvm.org/D97107
1 parent 22e9753 commit 1ce846b

File tree

5 files changed

+89
-1
lines changed

5 files changed

+89
-1
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fopenmp %s -emit-llvm -o - | FileCheck %s
2+
3+
void __test_offloading_42_abcdef_bar_l123();
4+
void use(int);
5+
6+
void foo(int a)
7+
{
8+
#pragma omp target
9+
use(a);
10+
11+
__test_offloading_42_abcdef_bar_l123();
12+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --include-generated-funcs --replace-function-regex "__([a-z]+)_offloading_[a-z0-9]+_[a-z0-9]+_(.*)_l[0-9]+"
2+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fopenmp %s -emit-llvm -o - | FileCheck %s
3+
4+
void __test_offloading_42_abcdef_bar_l123();
5+
void use(int);
6+
7+
void foo(int a)
8+
{
9+
#pragma omp target
10+
use(a);
11+
12+
__test_offloading_42_abcdef_bar_l123();
13+
}
14+
// CHECK-LABEL: @foo(
15+
// CHECK-NEXT: entry:
16+
// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4
17+
// CHECK-NEXT: [[A_CASTED:%.*]] = alloca i64, align 8
18+
// CHECK-NEXT: store i32 [[A:%.*]], i32* [[A_ADDR]], align 4
19+
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A_ADDR]], align 4
20+
// CHECK-NEXT: [[CONV:%.*]] = bitcast i64* [[A_CASTED]] to i32*
21+
// CHECK-NEXT: store i32 [[TMP0]], i32* [[CONV]], align 4
22+
// CHECK-NEXT: [[TMP1:%.*]] = load i64, i64* [[A_CASTED]], align 8
23+
// CHECK-NEXT: call void @{{__omp_offloading_[a-z0-9]+_[a-z0-9]+_foo_l[0-9]+}}(i64 [[TMP1]]) #[[ATTR3:[0-9]+]]
24+
// CHECK-NEXT: call void (...) @{{__test_offloading_[a-z0-9]+_[a-z0-9]+_bar_l[0-9]+}}()
25+
// CHECK-NEXT: ret void
26+
//
27+
//
28+
// CHECK-LABEL: @{{__omp_offloading_[a-z0-9]+_[a-z0-9]+_foo_l[0-9]+}}(
29+
// CHECK-NEXT: entry:
30+
// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i64, align 8
31+
// CHECK-NEXT: store i64 [[A:%.*]], i64* [[A_ADDR]], align 8
32+
// CHECK-NEXT: [[CONV:%.*]] = bitcast i64* [[A_ADDR]] to i32*
33+
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[CONV]], align 8
34+
// CHECK-NEXT: call void @use(i32 [[TMP0]])
35+
// CHECK-NEXT: ret void
36+
//
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
## Test that CHECK lines are generated for clang-generated functions replaced
2+
## by regex
3+
4+
## RUN: cp %S/Inputs/generated-funcs-regex.c %t-generated-funcs-regex.c && %update_cc_test_checks --include-generated-funcs --replace-function-regex "__([a-z]+)_offloading_[a-z0-9]+_[a-z0-9]+_(.*)_l[0-9]+" -- %t-generated-funcs-regex.c
5+
# RUN: diff -u %S/Inputs/generated-funcs-regex.c.expected %t-generated-funcs-regex.c
6+
7+
## Check that re-running update_cc_test_checks doesn't change the output
8+
# RUN: %update_cc_test_checks %t-generated-funcs-regex.c
9+
# RUN: diff -u %S/Inputs/generated-funcs-regex.c.expected %t-generated-funcs-regex.c

llvm/utils/UpdateTestChecks/common.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ def parse_commandline_args(parser):
3030
help='Activate CHECK line generation from this point forward')
3131
parser.add_argument('--disable', action='store_false', dest='enabled',
3232
help='Deactivate CHECK line generation from this point forward')
33+
parser.add_argument('--replace-function-regex', nargs='+', default=[],
34+
help='List of regular expressions to replace matching function names')
3335
args = parser.parse_args()
3436
global _verbose
3537
_verbose = args.verbose
@@ -275,6 +277,8 @@ def __init__(self, run_list, flags, scrubber_args):
275277
self._record_args = flags.function_signature
276278
self._check_attributes = flags.check_attributes
277279
self._scrubber_args = scrubber_args
280+
# Strip double-quotes if input was read by UTC_ARGS
281+
self._replace_function_regex = list(map(lambda x: x.strip('"'), flags.replace_function_regex))
278282
self._func_dict = {}
279283
self._func_order = {}
280284
self._global_var_dict = {}
@@ -348,6 +352,30 @@ def process_run_line(self, function_re, scrubber, raw_tool_output, prefixes):
348352
self._func_dict[prefix][func] = None
349353
continue
350354

355+
# Replace function names matching the regex.
356+
for regex in self._replace_function_regex:
357+
# Pattern that matches capture groups in the regex in leftmost order.
358+
group_regex = re.compile('\(.*?\)')
359+
# Replace function name with regex.
360+
match = re.match(regex, func)
361+
if match:
362+
func_repl = regex
363+
# Replace any capture groups with their matched strings.
364+
for g in match.groups():
365+
func_repl = group_regex.sub(g, func_repl, count=1)
366+
func = '{{' + func_repl + '}}'
367+
368+
# Replace all calls to regex matching functions.
369+
matches = re.finditer(regex, scrubbed_body)
370+
for match in matches:
371+
func_repl = regex
372+
# Replace any capture groups with their matched strings.
373+
for g in match.groups():
374+
func_repl = group_regex.sub(g, func_repl, count=1)
375+
# Substitute function call names that match the regex with the same
376+
# capture groups set.
377+
scrubbed_body = re.sub(func_repl, '{{' + func_repl + '}}', scrubbed_body)
378+
351379
self._func_dict[prefix][func] = function_body(
352380
scrubbed_body, scrubbed_extra, args_and_sig, attrs)
353381
self._func_order[prefix].append(func)
@@ -794,6 +822,8 @@ def get_autogennote_suffix(parser, args):
794822
continue # Don't add default values
795823
autogenerated_note_args += action.option_strings[0] + ' '
796824
if action.const is None: # action takes a parameter
825+
if action.nargs == '+':
826+
value = ' '.join(map(lambda v: '"' + v.strip('"') + '"', value))
797827
autogenerated_note_args += '%s ' % value
798828
if autogenerated_note_args:
799829
autogenerated_note_args = ' %s %s' % (UTC_ARGS_KEY, autogenerated_note_args[:-1])

llvm/utils/update_llc_test_checks.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,8 @@ def main():
109109
flags=type('', (object,), {
110110
'verbose': ti.args.verbose,
111111
'function_signature': False,
112-
'check_attributes': False}),
112+
'check_attributes': False,
113+
'replace_function_regex': []}),
113114
scrubber_args=[ti.args])
114115

115116
for prefixes, llc_args, triple_in_cmd, march_in_cmd in run_list:

0 commit comments

Comments
 (0)