1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00
llvm-mirror/test/CodeGen/AArch64/GlobalISel/legalizer-combiner-zext-trunc-crash.mir
Roman Tereshin 4bdb48ce84 [Legalizer] Making artifact combining order-independent
Legalization algorithm is complicated by two facts:
1) While regular instructions should be possible to legalize in
   an isolated, per-instruction, context-free manner, legalization
   artifacts can only be eliminated in pairs, which could be deeply, and
   ultimately arbitrary nested: { [ () ] }, where which paranthesis kind
   depicts an artifact kind, like extend, unmerge, etc. Such structure
   can only be fully eliminated by simple local combines if they are
   attempted in a particular order (inside out), or alternatively by
   repeated scans each eliminating only one innermost pair, resulting in
   O(n^2) complexity.
2) Some artifacts might in fact be regular instructions that could (and
   sometimes should) be legalized by the target-specific rules. Which
   means failure to eliminate all artifacts on the first iteration is
   not a failure, they need to be tried as instructions, which may
   produce more artifacts, including the ones that are in fact regular
   instructions, resulting in a non-constant number of iterations
   required to finish the process.

I trust the recently introduced termination condition (no new artifacts
were created during as-a-regular-instruction-retrial of artifacts not
eliminated on the previous iteration) to be efficient in providing
termination, but only performing the legalization in full if and only if
at each step such chains of artifacts are successfully eliminated in
full as well.

Which is currently not guaranteed, as the artifact combines are applied
only once and in an arbitrary order that has to do with the order of
creation or insertion of artifacts into their worklist, which is a no
particular order.

In this patch I make a small change to the artifact combiner, making it
to re-insert into the worklist immediate (modulo a look-through copies)
artifact users of each vreg that changes its definition due to an
artifact combine.

Here the first scan through the artifacts worklist, while not
being done in any guaranteed order, only needs to find the innermost
pair(s) of artifacts that could be immediately combined out. After that
the process follows def-use chains, making them shorter at each step, thus
combining everything that can be combined in O(n) time.

Reviewers: volkan, aditya_nandakumar, qcolombet, paquette, aemerson, dsanders

Reviewed By: aditya_nandakumar, paquette

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D71448
2019-12-13 15:45:18 -08:00

67 lines
2.7 KiB
YAML

# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -mtriple aarch64 -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
# This test checks we don't crash when doing zext(trunc) legalizer combines.
---
name: zext_trunc_dead_inst_crash
alignment: 4
tracksRegLiveness: true
body: |
; CHECK-LABEL: name: zext_trunc_dead_inst_crash
; CHECK: bb.0:
; CHECK: successors: %bb.1(0x80000000)
; CHECK: [[DEF:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
; CHECK: bb.1:
; CHECK: successors: %bb.2(0x80000000)
; CHECK: [[PHI:%[0-9]+]]:_(s16) = G_PHI %32(s16), %bb.2, [[DEF]](s16), %bb.0
; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[PHI]](s16)
; CHECK: [[AND:%[0-9]+]]:_(s32) = G_AND [[ANYEXT]], [[C]]
; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 46
; CHECK: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(eq), [[AND]](s32), [[C1]]
; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY [[ICMP]](s32)
; CHECK: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
; CHECK: [[OR:%[0-9]+]]:_(s32) = G_OR [[COPY]], [[DEF1]]
; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY [[ANYEXT]](s32)
; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 -33
; CHECK: [[AND1:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C2]]
; CHECK: [[COPY2:%[0-9]+]]:_(s32) = COPY [[AND1]](s32)
; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 -65
; CHECK: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY2]], [[C3]]
; CHECK: [[COPY3:%[0-9]+]]:_(s32) = COPY [[ADD]](s32)
; CHECK: [[AND2:%[0-9]+]]:_(s32) = G_AND [[COPY3]], [[C]]
; CHECK: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 26
; CHECK: [[ICMP1:%[0-9]+]]:_(s32) = G_ICMP intpred(ult), [[AND2]](s32), [[C4]]
; CHECK: [[COPY4:%[0-9]+]]:_(s32) = COPY [[ICMP1]](s32)
; CHECK: [[COPY5:%[0-9]+]]:_(s32) = COPY [[OR]](s32)
; CHECK: [[OR1:%[0-9]+]]:_(s32) = G_OR [[COPY4]], [[COPY5]]
; CHECK: [[TRUNC:%[0-9]+]]:_(s1) = G_TRUNC [[OR1]](s32)
; CHECK: G_BRCOND [[TRUNC]](s1), %bb.2
; CHECK: bb.2:
; CHECK: successors: %bb.1(0x80000000)
; CHECK: [[C5:%[0-9]+]]:_(s16) = G_CONSTANT i16 64
; CHECK: G_BR %bb.1
bb.1:
%1:_(s8) = G_CONSTANT i8 46
%3:_(s1) = G_IMPLICIT_DEF
%5:_(s8) = G_CONSTANT i8 -33
%7:_(s8) = G_CONSTANT i8 -65
%9:_(s8) = G_CONSTANT i8 26
%13:_(s8) = G_IMPLICIT_DEF
bb.2:
%0:_(s8) = G_PHI %12(s8), %bb.4, %13(s8), %bb.1
%2:_(s1) = G_ICMP intpred(eq), %0(s8), %1
%4:_(s1) = G_OR %2, %3
%6:_(s8) = G_AND %0, %5
%8:_(s8) = G_ADD %6, %7
%10:_(s1) = G_ICMP intpred(ult), %8(s8), %9
%11:_(s1) = G_OR %10, %4
G_BRCOND %11(s1), %bb.4
bb.4:
%12:_(s8) = G_CONSTANT i8 64
G_BR %bb.2
...