Skip to content

Commit 045b827

Browse files
authored
[GlobalISel] Use-Vector-Truncate Opt Needs Elt Type Check (#146003)
In the pre-legalizer combiner, there exists a bug with UseVectorTruncate match-apply optimization. When the destinations' types do not match the vector element type of the G_UNMERGE_VALUES instruction, the resulting collapsed truncate does not preserve original functional behavior. This commit introduces a simple type check to ensure that the destination types match the vector element type.
1 parent 8a839ea commit 045b827

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3487,6 +3487,13 @@ bool CombinerHelper::matchUseVectorTruncate(MachineInstr &MI,
34873487
if (!DstTy.getElementCount().isKnownMultipleOf(UnmergeSrcTy.getNumElements()))
34883488
return false;
34893489

3490+
// Check the unmerge source and destination element types match
3491+
LLT UnmergeSrcEltTy = UnmergeSrcTy.getElementType();
3492+
Register UnmergeDstReg = UnmergeMI->getOperand(0).getReg();
3493+
LLT UnmergeDstEltTy = MRI.getType(UnmergeDstReg);
3494+
if (UnmergeSrcEltTy != UnmergeDstEltTy)
3495+
return false;
3496+
34903497
// Only generate legal instructions post-legalizer
34913498
if (!IsPreLegalize) {
34923499
LLT MidTy = DstTy.changeElementType(UnmergeSrcTy.getScalarType());
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
# RUN: llc -mtriple=aarch64 -run-pass=aarch64-prelegalizer-combiner %s -o - | FileCheck %s
3+
---
4+
name: test_foldable_s32
5+
body: |
6+
bb.0:
7+
liveins: $x0, $x1
8+
9+
; CHECK-LABEL: name: test_foldable_s32
10+
; CHECK: liveins: $x0, $x1
11+
; CHECK-NEXT: {{ $}}
12+
; CHECK-NEXT: [[SRC:%src]]:_(<2 x s32>) = COPY $x1
13+
; CHECK-NEXT: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
14+
; CHECK-NEXT: [[MID:%[0-9]+]]:_(<4 x s32>) = G_CONCAT_VECTORS [[SRC]](<2 x s32>), [[UNDEF]](<2 x s32>)
15+
; CHECK-NEXT: [[DST:%dst]]:_(<4 x s16>) = G_TRUNC [[MID]]
16+
; CHECK-NEXT: $x0 = COPY [[DST]]
17+
18+
%src:_(<2 x s32>) = COPY $x1
19+
%a:_(s32), %b:_(s32) = G_UNMERGE_VALUES %src:_(<2 x s32>)
20+
%T_a:_(s16) = G_TRUNC %a:_(s32)
21+
%T_b:_(s16) = G_TRUNC %b:_(s32)
22+
%Undef:_(s16) = G_IMPLICIT_DEF
23+
%dst:_(<4 x s16>) = G_BUILD_VECTOR %T_a:_(s16), %T_b:_(s16), %Undef:_(s16), %Undef:_(s16)
24+
$x0 = COPY %dst
25+
...
26+
---
27+
name: test_unfoldable_s32
28+
body: |
29+
bb.0:
30+
liveins: $w0, $x1
31+
32+
; CHECK-LABEL: name: test_unfoldable_s32
33+
; CHECK: liveins: $w0, $x1
34+
; CHECK-NEXT: {{ $}}
35+
; CHECK-NEXT: [[SRC:%src]]:_(<2 x s32>) = COPY $x1
36+
; CHECK-NEXT: [[A:%a]]:_(s16), [[B:%b]]:_(s16), [[C:%c]]:_(s16), %d:_(s16) = G_UNMERGE_VALUES [[SRC]](<2 x s32>)
37+
; CHECK-NEXT: [[T_A:%T_a]]:_(s8) = G_TRUNC [[A]](s16)
38+
; CHECK-NEXT: [[T_B:%T_b]]:_(s8) = G_TRUNC [[B]](s16)
39+
; CHECK-NEXT: [[T_C:%T_c]]:_(s8) = G_TRUNC [[C]](s16)
40+
; CHECK-NEXT: [[UNDEF:%Undef]]:_(s8) = G_IMPLICIT_DEF
41+
; CHECK-NEXT: [[DST:%dst]]:_(<4 x s8>) = G_BUILD_VECTOR [[T_A]](s8), [[T_B]](s8), [[T_C]](s8), [[UNDEF]](s8)
42+
; CHECK-NEXT: $w0 = COPY [[DST]](<4 x s8>)
43+
%src:_(<2 x s32>) = COPY $x1
44+
%a:_(s16), %b:_(s16), %c:_(s16), %d:_(s16) = G_UNMERGE_VALUES %src:_(<2 x s32>)
45+
%T_a:_(s8) = G_TRUNC %a:_(s16)
46+
%T_b:_(s8) = G_TRUNC %b:_(s16)
47+
%T_c:_(s8) = G_TRUNC %c:_(s16)
48+
%Undef:_(s8) = G_IMPLICIT_DEF
49+
%dst:_(<4 x s8>) = G_BUILD_VECTOR %T_a:_(s8), %T_b:_(s8), %T_c:_(s8), %Undef:_(s8)
50+
$w0 = COPY %dst
51+
52+
...

0 commit comments

Comments
 (0)