[UTC] Enable --function-signature by default
This patch enables --function-signature by default under --version 2 and makes --version 2 the default. This means that all newly created tests will check the function signature, while leaving old tests alone. There's two motivations for this change: * Without --function-signature, the generated check lines may fail in a very hard to understand way if the test both includes a function definition and a call to that function. (Though we could address this by making the CHECK-LABEL stricter, without checking the full signature.) * This actually checks that uses of the arguments in the function body use the correct argument, instead of matching against any variable. This is a replacement for D139006 and D140212 based on the --version mechanism. I did not include an opt-out flag --no-function-signature because I'm not sure we need it. Would be happy to include it though, if desired. Differential Revision: https://reviews.llvm.org/D145149
This commit is contained in:
parent
144e236441
commit
fb309041f0
|
@ -1,4 +1,4 @@
|
|||
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --version 2
|
||||
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2
|
||||
// Example input for update_cc_test_checks
|
||||
// RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
|
||||
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --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;
|
||||
}
|
|
@ -19,3 +19,8 @@
|
|||
## 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
|
||||
## Restore the original file without --function-signature and check that
|
||||
## --version 2 will implicitly enable it.
|
||||
# RUN: cp -f %S/Inputs/mangled_names.c %t.c
|
||||
# RUN: %update_cc_test_checks %t.c --version 2
|
||||
# RUN: diff -u %t.c %S/Inputs/mangled_names.c.v2.expected
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
|
||||
; Example input for update_test_checks (taken from test/Transforms/InstSimplify/add.ll)
|
||||
; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
|
||||
|
||||
define i32 @common_sub_operand(i32 %X, i32 %Y) {
|
||||
; CHECK-LABEL: define i32 @common_sub_operand
|
||||
; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) {
|
||||
; CHECK-NEXT: ret i32 [[X]]
|
||||
;
|
||||
%Z = sub i32 %X, %Y
|
||||
%Q = add i32 %Z, %Y
|
||||
ret i32 %Q
|
||||
}
|
||||
|
||||
define i32 @negated_operand(i32 %x) {
|
||||
; CHECK-LABEL: define i32 @negated_operand
|
||||
; CHECK-SAME: (i32 [[X:%.*]]) {
|
||||
; CHECK-NEXT: ret i32 0
|
||||
;
|
||||
%negx = sub i32 0, %x
|
||||
%r = add i32 %negx, %x
|
||||
ret i32 %r
|
||||
}
|
||||
|
||||
define <2 x i32> @negated_operand_commute_vec(<2 x i32> %x) {
|
||||
; CHECK-LABEL: define <2 x i32> @negated_operand_commute_vec
|
||||
; CHECK-SAME: (<2 x i32> [[X:%.*]]) {
|
||||
; CHECK-NEXT: ret <2 x i32> zeroinitializer
|
||||
;
|
||||
%negx = sub <2 x i32> zeroinitializer, %x
|
||||
%r = add <2 x i32> %x, %negx
|
||||
ret <2 x i32> %r
|
||||
}
|
||||
|
||||
define i8 @knownnegation(i8 %x, i8 %y) {
|
||||
; CHECK-LABEL: define i8 @knownnegation
|
||||
; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
|
||||
; CHECK-NEXT: ret i8 0
|
||||
;
|
||||
%xy = sub i8 %x, %y
|
||||
%yx = sub i8 %y, %x
|
||||
%r = add i8 %xy, %yx
|
||||
ret i8 %r
|
||||
}
|
||||
|
||||
define <2 x i8> @knownnegation_commute_vec(<2 x i8> %x, <2 x i8> %y) {
|
||||
; CHECK-LABEL: define <2 x i8> @knownnegation_commute_vec
|
||||
; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {
|
||||
; CHECK-NEXT: ret <2 x i8> zeroinitializer
|
||||
;
|
||||
%xy = sub <2 x i8> %x, %y
|
||||
%yx = sub <2 x i8> %y, %x
|
||||
%r = add <2 x i8> %yx, %xy
|
||||
ret <2 x i8> %r
|
||||
}
|
||||
|
||||
define i32 @nameless_value(i32 %X) {
|
||||
; CHECK-LABEL: define i32 @nameless_value
|
||||
; CHECK-SAME: (i32 [[X:%.*]]) {
|
||||
; CHECK-NEXT: [[TMP1:%.*]] = sub i32 42, [[X]]
|
||||
; CHECK-NEXT: ret i32 [[TMP1]]
|
||||
;
|
||||
%1 = sub i32 42, %X
|
||||
ret i32 %1
|
||||
}
|
|
@ -14,3 +14,8 @@
|
|||
## added to the update invocation below.
|
||||
# RUN: %update_test_checks %t.ll
|
||||
# RUN: diff -u %t.ll %S/Inputs/basic.ll.funcsig.expected
|
||||
## Restore the original file without --function-signature and check that
|
||||
## --version 2 will implicitly enable it and also check the return type.
|
||||
# RUN: cp -f %S/Inputs/basic.ll %t.ll
|
||||
# RUN: %update_test_checks %t.ll --version 2
|
||||
# RUN: diff -u %t.ll %S/Inputs/basic.ll.v2.expected
|
||||
|
|
|
@ -22,9 +22,10 @@ _prefix_filecheck_ir_name = ''
|
|||
Version changelog:
|
||||
|
||||
1: Initial version, used by tests that don't specify --version explicitly.
|
||||
2: --function-signature now also checks return type/attributes.
|
||||
2: --function-signature is now enabled by default and also checks return
|
||||
type/attributes.
|
||||
"""
|
||||
DEFAULT_VERSION = 1
|
||||
DEFAULT_VERSION = 2
|
||||
|
||||
class Regex(object):
|
||||
"""Wrap a compiled regular expression object to allow deep copy of a regexp.
|
||||
|
@ -157,6 +158,11 @@ def parse_commandline_args(parser):
|
|||
_global_hex_value_regex = args.global_hex_value_regex
|
||||
return args
|
||||
|
||||
def parse_args(parser, argv):
|
||||
args = parser.parse_args(argv)
|
||||
if args.version >= 2:
|
||||
args.function_signature = True
|
||||
return args
|
||||
|
||||
class InputLineInfo(object):
|
||||
def __init__(self, line, line_number, args, argv):
|
||||
|
@ -246,7 +252,7 @@ def itertests(test_patterns, parser, script_name, comment_prefix=None, argparse_
|
|||
if not is_regenerate:
|
||||
argv.insert(1, '--version=' + str(DEFAULT_VERSION))
|
||||
|
||||
args = parser.parse_args(argv[1:])
|
||||
args = parse_args(parser, argv[1:])
|
||||
if argparse_callback is not None:
|
||||
argparse_callback(args)
|
||||
if is_regenerate:
|
||||
|
@ -1199,6 +1205,8 @@ def get_autogennote_suffix(parser, args):
|
|||
continue
|
||||
if parser.get_default(action.dest) == value:
|
||||
continue # Don't add default values
|
||||
if action.dest == 'function_signature' and args.version >= 2:
|
||||
continue # Enabled by default in version 2
|
||||
if action.dest == 'filters':
|
||||
# Create a separate option for each filter element. The value is a list
|
||||
# of Filter objects.
|
||||
|
@ -1225,7 +1233,7 @@ def check_for_command(line, parser, args, argv, argparse_callback):
|
|||
for option in shlex.split(cmd_m.group('cmd').strip()):
|
||||
if option:
|
||||
argv.append(option)
|
||||
args = parser.parse_args(filter(lambda arg: arg not in args.tests, argv))
|
||||
args = parse_args(parser, filter(lambda arg: arg not in args.tests, argv))
|
||||
if argparse_callback is not None:
|
||||
argparse_callback(args)
|
||||
return args, argv
|
||||
|
|
Loading…
Reference in New Issue
Block a user