Skip to content

Commit b1fca54

Browse files
[LLVM][AArch64ExpandPseudo] Preserve undef flags when expanding SVE 1/2/3-op pseudo instructions. (#149104)
Fixes #149034
1 parent f04650b commit b1fca54

File tree

2 files changed

+93
-6
lines changed

2 files changed

+93
-6
lines changed

llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,9 @@ bool AArch64ExpandPseudo::expand_DestructiveOp(
598598
llvm_unreachable("Unsupported ElementSize");
599599
}
600600

601+
// Preserve undef state until DOP's reg is defined.
602+
unsigned DOPRegState = MI.getOperand(DOPIdx).isUndef() ? RegState::Undef : 0;
603+
601604
//
602605
// Create the destructive operation (if required)
603606
//
@@ -616,10 +619,11 @@ bool AArch64ExpandPseudo::expand_DestructiveOp(
616619
PRFX = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(MovPrfxZero))
617620
.addReg(DstReg, RegState::Define)
618621
.addReg(MI.getOperand(PredIdx).getReg())
619-
.addReg(MI.getOperand(DOPIdx).getReg());
622+
.addReg(MI.getOperand(DOPIdx).getReg(), DOPRegState);
620623

621624
// After the movprfx, the destructive operand is same as Dst
622625
DOPIdx = 0;
626+
DOPRegState = 0;
623627

624628
// Create the additional LSL to zero the lanes when the DstReg is not
625629
// unique. Zeros the lanes in z0 that aren't active in p0 with sequence
@@ -638,19 +642,21 @@ bool AArch64ExpandPseudo::expand_DestructiveOp(
638642
assert(DOPRegIsUnique && "The destructive operand should be unique");
639643
PRFX = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(MovPrfx))
640644
.addReg(DstReg, RegState::Define)
641-
.addReg(MI.getOperand(DOPIdx).getReg());
645+
.addReg(MI.getOperand(DOPIdx).getReg(), DOPRegState);
642646
DOPIdx = 0;
647+
DOPRegState = 0;
643648
}
644649

645650
//
646651
// Create the destructive operation
647652
//
648653
DOP = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opcode))
649654
.addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead));
655+
DOPRegState = DOPRegState | RegState::Kill;
650656

651657
switch (DType) {
652658
case AArch64::DestructiveUnaryPassthru:
653-
DOP.addReg(MI.getOperand(DOPIdx).getReg(), RegState::Kill)
659+
DOP.addReg(MI.getOperand(DOPIdx).getReg(), DOPRegState)
654660
.add(MI.getOperand(PredIdx))
655661
.add(MI.getOperand(SrcIdx));
656662
break;
@@ -659,12 +665,12 @@ bool AArch64ExpandPseudo::expand_DestructiveOp(
659665
case AArch64::DestructiveBinaryComm:
660666
case AArch64::DestructiveBinaryCommWithRev:
661667
DOP.add(MI.getOperand(PredIdx))
662-
.addReg(MI.getOperand(DOPIdx).getReg(), RegState::Kill)
663-
.add(MI.getOperand(SrcIdx));
668+
.addReg(MI.getOperand(DOPIdx).getReg(), DOPRegState)
669+
.add(MI.getOperand(SrcIdx));
664670
break;
665671
case AArch64::DestructiveTernaryCommWithRev:
666672
DOP.add(MI.getOperand(PredIdx))
667-
.addReg(MI.getOperand(DOPIdx).getReg(), RegState::Kill)
673+
.addReg(MI.getOperand(DOPIdx).getReg(), DOPRegState)
668674
.add(MI.getOperand(SrcIdx))
669675
.add(MI.getOperand(Src2Idx));
670676
break;

llvm/test/CodeGen/AArch64/sve-pseudos-expand-undef.mir

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,84 @@ body: |
5454
renamable $z0 = FADD_ZPZZ_D_UNDEF killed $p0, killed $z1, killed $z2, implicit-def $z0_z1_z2_z3
5555
RET_ReallyLR implicit $z0_z1_z2_z3
5656
...
57+
58+
---
59+
name: unary_undef_operand
60+
body: |
61+
bb.0:
62+
liveins: $p0, $z0
63+
64+
; CHECK: name: unary_undef_operand
65+
; CHECK: $z0 = MOVPRFX_ZZ undef $z1
66+
; CHECK: $z0 = ABS_ZPmZ_S internal killed $z0, renamable $p0, killed undef renamable $z1
67+
; NOTE: Unary _UNDEF psuedo instructions ignore the passthru operand.
68+
renamable $z0 = ABS_ZPmZ_S_UNDEF renamable $z0, renamable $p0, killed undef renamable $z1
69+
RET_ReallyLR
70+
71+
...
72+
73+
---
74+
name: binop_undef_operand
75+
body: |
76+
bb.0:
77+
liveins: $p0, $z1
78+
79+
; CHECK: name: binop_undef_operand
80+
; CHECK-NOT: MOVPRFX
81+
; CHECK: $z0 = SMIN_ZPmZ_S renamable $p0, killed undef $z0, killed renamable $z1
82+
renamable $z0 = SMIN_ZPZZ_S_UNDEF renamable $p0, undef renamable $z0, killed renamable $z1
83+
RET_ReallyLR
84+
85+
...
86+
87+
---
88+
name: binop_undef_operand_requires_movpfrx
89+
body: |
90+
bb.0:
91+
liveins: $p0, $z1
92+
93+
; CHECK: name: binop_undef_operand_requires_movpfrx
94+
; CHECK: $z0 = MOVPRFX_ZZ undef $z2
95+
; CHECK: $z0 = SMIN_ZPmZ_S renamable $p0, internal killed $z0, killed renamable $z1
96+
renamable $z0 = SMIN_ZPZZ_S_UNDEF renamable $p0, undef renamable $z2, killed renamable $z1
97+
RET_ReallyLR
98+
99+
...
100+
101+
---
102+
name: binop_undef_operand_requires_zeroing_movpfrx
103+
body: |
104+
bb.0:
105+
liveins: $p0, $z1
106+
107+
; CHECK: name: binop_undef_operand_requires_zeroing_movpfrx
108+
; CHECK: $z0 = MOVPRFX_ZPzZ_S $p0, undef $z2
109+
; CHECK: $z0 = ADD_ZPmZ_S renamable $p0, internal killed $z0, killed renamable $z1
110+
renamable $z0 = ADD_ZPZZ_S_ZERO renamable $p0, undef renamable $z2, killed renamable $z1
111+
RET_ReallyLR
112+
113+
...
114+
115+
---
116+
name: ternaryop_undef_operand
117+
body: |
118+
bb.0:
119+
liveins: $p0, $z1, $z2
120+
; CHECK: name: ternaryop_undef_operand
121+
; CHECK-NOT: MOVPRFX
122+
; CHECK: $z0 = MLA_ZPmZZ_B killed renamable $p0, killed undef $z0, killed renamable $z1, killed renamable $z2
123+
renamable $z0 = MLA_ZPZZZ_B_UNDEF killed renamable $p0, killed undef renamable $z0, killed renamable $z1, killed renamable $z2
124+
RET_ReallyLR implicit $z0
125+
...
126+
127+
---
128+
name: ternaryop_undef_operand_requires_movprfx
129+
body: |
130+
bb.0:
131+
liveins: $p0, $z1, $z2
132+
; CHECK: name: ternaryop_undef_operand_requires_movprfx
133+
; CHECK: $z0 = MOVPRFX_ZZ undef $z3
134+
; CHECK: $z0 = MLA_ZPmZZ_B killed renamable $p0, internal killed $z0, killed renamable $z1, killed renamable $z2
135+
renamable $z0 = MLA_ZPZZZ_B_UNDEF killed renamable $p0, killed undef renamable $z3, killed renamable $z1, killed renamable $z2
136+
RET_ReallyLR implicit $z0
137+
...

0 commit comments

Comments
 (0)