1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 04:02:41 +01:00

[utils] Fix UpdateTestChecks case where 2 runs differ for last label

Two RUN lines produce outputs that, each, have some common parts and
some different parts. The common parts are checked under label A. The
differing parts are associated to a function and checked under labels B
and C, respectivelly.
When build_function_body_dictionary is called for the first RUN line, it
will attribute the function body to labels A and C. When the second RUN
is passed to build_function_body_dictionary, it sees that the function
body under A is different from what it has. If in this second RUN line,
A were at the end of the prefixes list, A's body is still kept
associated with the first run's function.

When we output the function body (i.e. add_checks), we stop after
emitting for the first prefix matching that function. So we end up with
the wrong function body (first RUN's A-association).

There is no reason to special-case the last label in the prefixes list,
and the fix is to always clear a label association if we find a RUN line
where the body is different.

Differential Revision: https://reviews.llvm.org/D93078
This commit is contained in:
Mircea Trofin 2020-12-10 16:15:18 -08:00
parent 43edfa5357
commit 03a62f3073
10 changed files with 108 additions and 8 deletions

View File

@ -0,0 +1,11 @@
; RUN: llc < %s -mtriple=i686-unknown-linux-gnu -mattr=+sse2 | FileCheck %s --check-prefixes=A,B
; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s --allow-unused-prefixes=true --check-prefixes=C,A,UNUSED
declare <2 x i64> @llvm.bswap.v2i64(<2 x i64>)
; A: declare <2 x i64> @llvm.bswap.v2i64(<2 x i64>)
define <2 x i64> @fold_v2i64() {
entry:
%r = call <2 x i64> @llvm.bswap.v2i64(<2 x i64> <i64 255, i64 -1>)
ret <2 x i64> %r
}

View File

@ -0,0 +1,11 @@
; RUN: llc < %s -mtriple=i686-unknown-linux-gnu -mattr=+sse2 | FileCheck %s --check-prefixes=A,B
; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s --check-prefixes=C,A
declare <2 x i64> @llvm.bswap.v2i64(<2 x i64>)
; A: declare <2 x i64> @llvm.bswap.v2i64(<2 x i64>)
define <2 x i64> @fold_v2i64() {
entry:
%r = call <2 x i64> @llvm.bswap.v2i64(<2 x i64> <i64 255, i64 -1>)
ret <2 x i64> %r
}

View File

@ -0,0 +1,11 @@
; RUN: llc < %s -mtriple=i686-unknown-linux-gnu -mattr=+sse2 | FileCheck %s --check-prefixes=A,B
; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s --check-prefixes=A,C
declare <2 x i64> @llvm.bswap.v2i64(<2 x i64>)
; A: declare <2 x i64> @llvm.bswap.v2i64(<2 x i64>)
define <2 x i64> @fold_v2i64() {
entry:
%r = call <2 x i64> @llvm.bswap.v2i64(<2 x i64> <i64 255, i64 -1>)
ret <2 x i64> %r
}

View File

@ -0,0 +1,10 @@
; RUN: llc < %s -mtriple=i686-unknown-linux-gnu -mattr=+sse2 | FileCheck %s --check-prefixes=A
; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s --check-prefixes=A
declare <2 x i64> @llvm.bswap.v2i64(<2 x i64>)
define <2 x i64> @fold_v2i64() {
entry:
%r = call <2 x i64> @llvm.bswap.v2i64(<2 x i64> <i64 255, i64 -1>)
ret <2 x i64> %r
}

View File

@ -0,0 +1,14 @@
# REQUIRES: x86-registered-target
# RUN: cp -f %S/Inputs/common-label-different-bodies-1.ll %t-1.ll
# RUN: cp -f %S/Inputs/common-label-different-bodies-2.ll %t-2.ll
# RUN: cp -f %S/Inputs/common-label-different-bodies-3.ll %t-3.ll
# RUN: %update_llc_test_checks %t-1.ll
# RUN: %update_llc_test_checks %t-2.ll
# RUN: %update_llc_test_checks %t-3.ll
# RUN: FileCheck --input-file=%t-1.ll %s
# RUN: FileCheck --input-file=%t-2.ll %s
# RUN: FileCheck --input-file=%t-3.ll %s
# CHECK: B-LABEL: fold_v2i64
# CHECK-NOT: A-LABEL: fold_v2i64

View File

@ -0,0 +1,8 @@
# REQUIRES: x86-registered-target
# RUN: cp -f %S/Inputs/prefix-never-matches.ll %t.ll
# RUN: %update_llc_test_checks %t.ll 2>&1 | FileCheck %s
# RUN: FileCheck --input-file=%t.ll %s --check-prefix=OUTPUT
# CHECK: WARNING: Prefix A had conflicting output
# OUTPUT-NOT: A:

View File

@ -0,0 +1,7 @@
; RUN: opt -O0 -S < %s | FileCheck %s -check-prefix=A
; RUN: opt -O3 -S < %s | FileCheck %s -check-prefix=A
define i32 @foo(i32 %i) {
%r = add i32 1, 1
ret i32 %r
}

View File

@ -0,0 +1,6 @@
# RUN: cp -f %S/Inputs/prefix-never-matches.ll %t.ll
# RUN: %update_test_checks %t.ll 2>&1 | FileCheck %s
# RUN: FileCheck --input-file=%t.ll %s --check-prefix=OUTPUT
# CHECK: WARNING: Prefix A had conflicting output
# OUTPUT-NOT: A:

View File

@ -258,6 +258,20 @@ class function_body(object):
def __str__(self): def __str__(self):
return self.scrub return self.scrub
def get_failed_prefixes(func_dict):
# This returns the list of those prefixes that failed to match any function,
# because there were conflicting bodies produced by different RUN lines, in
# all instances of the prefix. Effectivelly, this prefix is unused and should
# be removed.
for prefix in func_dict:
if (not [fct for fct in func_dict[prefix]
if func_dict[prefix][fct] is not None]):
yield prefix
def warn_on_failed_prefixes(func_dict):
for prefix in get_failed_prefixes(func_dict):
warn('Prefix %s had conflicting output from different RUN lines for all functions' % (prefix,))
def build_function_body_dictionary(function_re, scrubber, scrubber_args, raw_tool_output, prefixes, func_dict, func_order, verbose, record_args, check_attributes): def build_function_body_dictionary(function_re, scrubber, scrubber_args, raw_tool_output, prefixes, func_dict, func_order, verbose, record_args, check_attributes):
for m in function_re.finditer(raw_tool_output): for m in function_re.finditer(raw_tool_output):
if not m: if not m:
@ -287,20 +301,28 @@ def build_function_body_dictionary(function_re, scrubber, scrubber_args, raw_too
print(' ' + l, file=sys.stderr) print(' ' + l, file=sys.stderr)
for prefix in prefixes: for prefix in prefixes:
if func in func_dict[prefix]: if func in func_dict[prefix]:
if str(func_dict[prefix][func]) != scrubbed_body or (func_dict[prefix][func] and (func_dict[prefix][func].args_and_sig != args_and_sig or func_dict[prefix][func].attrs != attrs)): if (func_dict[prefix][func] is None or
if func_dict[prefix][func] and func_dict[prefix][func].is_same_except_arg_names(scrubbed_extra, args_and_sig, attrs): str(func_dict[prefix][func]) != scrubbed_body or
func_dict[prefix][func].args_and_sig != args_and_sig or
func_dict[prefix][func].attrs != attrs):
if (func_dict[prefix][func] is not None and
func_dict[prefix][func].is_same_except_arg_names(scrubbed_extra,
args_and_sig,
attrs)):
func_dict[prefix][func].scrub = scrubbed_extra func_dict[prefix][func].scrub = scrubbed_extra
func_dict[prefix][func].args_and_sig = args_and_sig func_dict[prefix][func].args_and_sig = args_and_sig
continue continue
else: else:
if prefix == prefixes[-1]: # This means a previous RUN line produced a body for this function
warn('Found conflicting asm under the same prefix: %r!' % (prefix,)) # that is different from the one produced by this current RUN line,
else: # so the body can't be common accross RUN lines. We use None to
# indicate that.
func_dict[prefix][func] = None func_dict[prefix][func] = None
continue continue
func_dict[prefix][func] = function_body(scrubbed_body, scrubbed_extra, args_and_sig, attrs) func_dict[prefix][func] = function_body(scrubbed_body, scrubbed_extra, args_and_sig, attrs)
func_order[prefix].append(func) func_order[prefix].append(func)
warn_on_failed_prefixes(func_dict)
##### Generator of LLVM IR CHECK lines ##### Generator of LLVM IR CHECK lines

View File

@ -31,7 +31,7 @@ def remove_prefix(i, d=0):
t = re.search('Assertions have been autogenerated by (.*)', s) t = re.search('Assertions have been autogenerated by (.*)', s)
if t: if t:
s = os.popen('llvm/' + t.group(1) + ' ' + i + ' 2>&1').read() s = os.popen('llvm/' + t.group(1) + ' ' + i + ' 2>&1').read()
if 'Found conflicting' in s: if 'had conflicting output from different RUN lines for all functions' in s:
return -1 return -1
s = os.popen('git diff ' + i).read() s = os.popen('git diff ' + i).read()
if re.search('\n(?:-+)\n', s) or re.search('\n[+-].*(?<!RUN):', s): if re.search('\n(?:-+)\n', s) or re.search('\n[+-].*(?<!RUN):', s):