Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[GlobalISel][AArch64] LegalizerInfo verifier: Adding LegalizerInfo::v…
…erify(...) call w/o fixing bugs This is to make it clear what kind of bugs the LegalizerInfo::verifier is able to catch and test its output Reviewers: aemerson, qcolombet Reviewed By: aemerson Differential Revision: https://reviews.llvm.org/D46338 llvm-svn: 333597
- Loading branch information
Showing
4 changed files
with
377 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
llvm/test/CodeGen/AArch64/GlobalISel/legalize-inttoptr-xfail-1.mir
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# RUN: not llc -mtriple=aarch64-- -run-pass=legalizer %s -o - 2>&1 | FileCheck %s | ||
# REQUIRES: asserts | ||
# XFAIL: * | ||
|
||
# This is to demonstrate what kind of bugs we're missing w/o some kind | ||
# of validation for LegalizerInfo: G_INTTOPTR could only be legal / | ||
# could be legalized if its destination operand has a pointer type and | ||
# its source - a scalar type. This is reversed in this test and the | ||
# legalizer is expected to fail on it with an appropriate error | ||
# message. Prior to LegalizerInfo::verify AArch64 legalizer had a | ||
# subtle bug in its definition that caused it to accept the following | ||
# MIR as legal. Namely, it checked that type index 0 is either s64 or | ||
# p0 (in that order) and implicitly declared any type for type index 1 | ||
# as legal. As LegalizerInfo::verify asserts on such a definition due | ||
# to type index 1 not being covered it forces to review the definition | ||
# and fix the mistake: check that type index 0 is p0 and type index 1 | ||
# is s64 (in that order). | ||
|
||
# CHECK: LLVM ERROR: unable to legalize instruction: | ||
# CHECK-SAME: %{{[0-9]+}}:_(s64) = G_INTTOPTR %{{[0-9]+}}:_(p0) | ||
# CHECK-SAME: (in function: broken) | ||
|
||
--- | ||
name: broken | ||
alignment: 2 | ||
tracksRegLiveness: true | ||
registers: | ||
- { id: 0, class: _ } | ||
- { id: 1, class: _ } | ||
body: | | ||
bb.1: | ||
liveins: $x0 | ||
%0:_(p0) = COPY $x0 | ||
%1:_(s64) = G_INTTOPTR %0(p0) | ||
$x0 = COPY %1(s64) | ||
RET_ReallyLR implicit $x0 | ||
... |
43 changes: 43 additions & 0 deletions
43
llvm/test/CodeGen/AArch64/GlobalISel/legalize-inttoptr-xfail-2.mir
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# RUN: not llc -mtriple=aarch64-- -run-pass=legalizer %s -o - 2>&1 | FileCheck %s | ||
# REQUIRES: asserts | ||
# XFAIL: * | ||
|
||
# This is to demonstrate what kind of bugs we're missing w/o some kind | ||
# of validation for LegalizerInfo: G_INTTOPTR could only be legal / | ||
# could be legalized if its destination operand has a pointer type and | ||
# its source - a scalar type of an appropriate size. This test meets | ||
# the requirements for type index 0 (the pointer) and LLT-size | ||
# requirements for type index 1 (64 bits for AArch64), but has a | ||
# non-scalar (vector) type for type index 1. The Legalizer is expected | ||
# to fail on it with an appropriate error message. Prior to | ||
# LegalizerInfo::verify AArch64 legalizer had a subtle bug in its | ||
# definition that caused it to accept the following MIR as legal. | ||
# Namely, it checked that type index 0 is either s64 or p0 and | ||
# implicitly declared any type for type index 1 as legal (as soon as | ||
# its size is 64 bits). As LegalizerInfo::verify asserts on such a | ||
# definition due to type index 1 not being covered by a specific | ||
# action (not just `unsupportedIf`) it forces to review the definition | ||
# and fix the mistake: check that type index 0 is p0 and type index 1 | ||
# is s64. | ||
|
||
# CHECK: LLVM ERROR: unable to legalize instruction: | ||
# CHECK-SAME: %{{[0-9]+}}:_(p0) = G_INTTOPTR %{{[0-9]+}}:_(<4 x s16>) | ||
# CHECK-SAME: (in function: broken) | ||
|
||
--- | ||
name: broken | ||
alignment: 2 | ||
tracksRegLiveness: true | ||
registers: | ||
- { id: 0, class: _ } | ||
- { id: 1, class: _ } | ||
body: | | ||
bb.1: | ||
liveins: $d0 | ||
%0:_(<4 x s16>) = COPY $d0 | ||
%1:_(p0) = G_INTTOPTR %0(<4 x s16>) | ||
$x0 = COPY %1(p0) | ||
RET_ReallyLR implicit $x0 | ||
... |
294 changes: 294 additions & 0 deletions
294
llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,294 @@ | ||
# RUN: llc -mtriple=aarch64-- -run-pass=legalizer %s \ | ||
# RUN: -mcpu=cortex-a75 -o - 2>&1 | FileCheck %s --check-prefixes=CHECK --match-full-lines | ||
|
||
# RUN: llc -mtriple=aarch64-- -run-pass=legalizer %s -debug-only=legalizer-info \ | ||
# RUN: -mcpu=cortex-a75 -o - 2>&1 | FileCheck %s --check-prefixes=CHECK,DEBUG --match-full-lines | ||
|
||
# REQUIRES: asserts | ||
|
||
# The main purpose of this test is to make sure we don't over-relax | ||
# LegalizerInfo validation and loose its ability to catch bugs. | ||
# | ||
# Watch out for every "SKIPPED: user-defined predicate detected" in the | ||
# check-lines below and keep each and every one of them justified. | ||
|
||
|
||
# DEBUG: G_ADD (opcode [[ADD_OPC:[0-9]+]]): 1 type index | ||
# DEBUG-NEXT: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_SUB (opcode [[SUB_OPC:[0-9]+]]): 1 type index | ||
# DEBUG-NEXT: .. opcode [[SUB_OPC]] is aliased to [[ADD_OPC]] | ||
# DEBUG-NEXT: .. opcode [[ADD_OPC]] is aliased to 0 | ||
# DEBUG-NEXT: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_MUL (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_SDIV (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_UDIV (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_SREM (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_UREM (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_AND (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_OR (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_XOR (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_IMPLICIT_DEF (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_PHI (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_FRAME_INDEX (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_GLOBAL_VALUE (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_EXTRACT (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. type index coverage check SKIPPED: user-defined predicate detected | ||
# | ||
# DEBUG-NEXT: G_UNMERGE_VALUES (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. type index coverage check SKIPPED: user-defined predicate detected | ||
# | ||
# DEBUG-NEXT: G_INSERT (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. type index coverage check SKIPPED: user-defined predicate detected | ||
# | ||
# DEBUG-NEXT: G_MERGE_VALUES (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. type index coverage check SKIPPED: user-defined predicate detected | ||
# | ||
# DEBUG-NEXT: G_PTRTOINT (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 2, OK | ||
# | ||
# DEBUG-NEXT: G_INTTOPTR (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 1, FAIL | ||
# | ||
# DEBUG-NEXT: G_BITCAST (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 2, OK | ||
# | ||
# DEBUG-NEXT: G_LOAD (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. type index coverage check SKIPPED: user-defined predicate detected | ||
# | ||
# DEBUG-NEXT: G_SEXTLOAD (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. type index coverage check SKIPPED: user-defined predicate detected | ||
# | ||
# DEBUG-NEXT: G_ZEXTLOAD (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. type index coverage check SKIPPED: user-defined predicate detected | ||
# | ||
# DEBUG-NEXT: G_STORE (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. type index coverage check SKIPPED: user-defined predicate detected | ||
# | ||
# DEBUG-NEXT: G_ATOMIC_CMPXCHG_WITH_SUCCESS (opcode {{[0-9]+}}): 3 type indices | ||
# DEBUG: .. the first uncovered type index: 1, FAIL | ||
# | ||
# DEBUG-NEXT: G_ATOMIC_CMPXCHG (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 2, OK | ||
# | ||
# DEBUG-NEXT: G_ATOMICRMW_XCHG (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 2, OK | ||
# | ||
# DEBUG-NEXT: G_ATOMICRMW_ADD (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 2, OK | ||
# | ||
# DEBUG-NEXT: G_ATOMICRMW_SUB (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 2, OK | ||
# | ||
# DEBUG-NEXT: G_ATOMICRMW_AND (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 2, OK | ||
# | ||
# DEBUG-NEXT: G_ATOMICRMW_NAND (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. type index coverage check SKIPPED: no rules defined | ||
# | ||
# DEBUG-NEXT: G_ATOMICRMW_OR (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 2, OK | ||
# | ||
# DEBUG-NEXT: G_ATOMICRMW_XOR (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 2, OK | ||
# | ||
# DEBUG-NEXT: G_ATOMICRMW_MAX (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 2, OK | ||
# | ||
# DEBUG-NEXT: G_ATOMICRMW_MIN (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 2, OK | ||
# | ||
# DEBUG-NEXT: G_ATOMICRMW_UMAX (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 2, OK | ||
# | ||
# DEBUG-NEXT: G_ATOMICRMW_UMIN (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 2, OK | ||
# | ||
# DEBUG-NEXT: G_BRCOND (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_BRINDIRECT (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_INTRINSIC (opcode {{[0-9]+}}): 0 type indices | ||
# DEBUG: .. type index coverage check SKIPPED: no rules defined | ||
# | ||
# DEBUG-NEXT: G_INTRINSIC_W_SIDE_EFFECTS (opcode {{[0-9]+}}): 0 type indices | ||
# DEBUG: .. type index coverage check SKIPPED: no rules defined | ||
# | ||
# DEBUG-NEXT: G_ANYEXT (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 1, FAIL | ||
# | ||
# DEBUG-NEXT: G_TRUNC (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. type index coverage check SKIPPED: no rules defined | ||
# | ||
# DEBUG-NEXT: G_CONSTANT (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_FCONSTANT (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_VASTART (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_VAARG (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 2, OK | ||
# | ||
# DEBUG-NEXT: G_SEXT (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 1, FAIL | ||
# | ||
# DEBUG-NEXT: G_ZEXT (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 1, FAIL | ||
# | ||
# DEBUG-NEXT: G_SHL (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_LSHR (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_ASHR (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_ICMP (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 2, OK | ||
# | ||
# DEBUG-NEXT: G_FCMP (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 2, OK | ||
# | ||
# DEBUG-NEXT: G_SELECT (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 2, OK | ||
# | ||
# DEBUG-NEXT: G_UADDE (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 2, OK | ||
# | ||
# DEBUG-NEXT: G_USUBE (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 2, OK | ||
# | ||
# DEBUG-NEXT: G_SADDO (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 2, OK | ||
# | ||
# DEBUG-NEXT: G_SSUBO (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 2, OK | ||
# | ||
# DEBUG-NEXT: G_UMULO (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 2, OK | ||
# | ||
# DEBUG-NEXT: G_SMULO (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 2, OK | ||
# | ||
# DEBUG-NEXT: G_UMULH (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_SMULH (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_FADD (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_FSUB (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_FMUL (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_FMA (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_FDIV (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_FREM (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_FPOW (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_FEXP (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. type index coverage check SKIPPED: no rules defined | ||
# | ||
# DEBUG-NEXT: G_FEXP2 (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. type index coverage check SKIPPED: no rules defined | ||
# | ||
# DEBUG-NEXT: G_FLOG (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. type index coverage check SKIPPED: no rules defined | ||
# | ||
# DEBUG-NEXT: G_FLOG2 (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. type index coverage check SKIPPED: no rules defined | ||
# | ||
# DEBUG-NEXT: G_FNEG (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. type index coverage check SKIPPED: no rules defined | ||
# | ||
# DEBUG-NEXT: G_FPEXT (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 2, OK | ||
# | ||
# DEBUG-NEXT: G_FPTRUNC (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 2, OK | ||
# | ||
# DEBUG-NEXT: G_FPTOSI (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 2, OK | ||
# | ||
# DEBUG-NEXT: G_FPTOUI (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 2, OK | ||
# | ||
# DEBUG-NEXT: G_SITOFP (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 2, OK | ||
# | ||
# DEBUG-NEXT: G_UITOFP (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 2, OK | ||
# | ||
# DEBUG-NEXT: G_FABS (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. type index coverage check SKIPPED: no rules defined | ||
# | ||
# DEBUG-NEXT: G_GEP (opcode {{[0-9]+}}): 2 type indices | ||
# DEBUG: .. the first uncovered type index: 2, OK | ||
# | ||
# DEBUG-NEXT: G_PTR_MASK (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
# | ||
# DEBUG-NEXT: G_BR (opcode {{[0-9]+}}): 0 type indices | ||
# DEBUG: .. type index coverage check SKIPPED: no rules defined | ||
# | ||
# DEBUG-NEXT: G_INSERT_VECTOR_ELT (opcode {{[0-9]+}}): 3 type indices | ||
# DEBUG: .. type index coverage check SKIPPED: no rules defined | ||
# | ||
# DEBUG-NEXT: G_EXTRACT_VECTOR_ELT (opcode {{[0-9]+}}): 3 type indices | ||
# DEBUG: .. type index coverage check SKIPPED: no rules defined | ||
# | ||
# DEBUG-NEXT: G_SHUFFLE_VECTOR (opcode {{[0-9]+}}): 3 type indices | ||
# DEBUG: .. type index coverage check SKIPPED: no rules defined | ||
# | ||
# DEBUG-NEXT: G_BSWAP (opcode {{[0-9]+}}): 1 type index | ||
# DEBUG: .. the first uncovered type index: 1, OK | ||
|
||
# CHECK: The following opcodes have ill-defined legalization rules: G_INTTOPTR G_ATOMIC_CMPXCHG_WITH_SUCCESS G_ANYEXT G_SEXT G_ZEXT | ||
|
||
--- | ||
name: dummy | ||
body: | | ||
bb.0: | ||
... |