Skip to content

Commit c5105c1

Browse files
authored
[GlobalISel] Fix bitcast fewerElements with scalar narrow types. (#153364)
For a <8 x i32> -> <2 x i128> bitcast, that under aarch64 is split into two halfs, the scalar i128 remainder was causing problems, causing a crash with invalid vector types. This makes sure they are handled correctly in fewerElementsBitcast.
1 parent 36c2a66 commit c5105c1

File tree

2 files changed

+37
-5
lines changed

2 files changed

+37
-5
lines changed

llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5574,12 +5574,19 @@ LegalizerHelper::fewerElementsBitcast(MachineInstr &MI, unsigned int TypeIdx,
55745574

55755575
unsigned NewElemCount =
55765576
NarrowTy.getSizeInBits() / SrcTy.getScalarSizeInBits();
5577-
LLT SrcNarrowTy = LLT::fixed_vector(NewElemCount, SrcTy.getElementType());
5578-
5579-
// Split the Src and Dst Reg into smaller registers
55805577
SmallVector<Register> SrcVRegs, BitcastVRegs;
5581-
if (extractGCDType(SrcVRegs, DstTy, SrcNarrowTy, SrcReg) != SrcNarrowTy)
5582-
return UnableToLegalize;
5578+
if (NewElemCount == 1) {
5579+
LLT SrcNarrowTy = SrcTy.getElementType();
5580+
5581+
auto Unmerge = MIRBuilder.buildUnmerge(SrcNarrowTy, SrcReg);
5582+
getUnmergeResults(SrcVRegs, *Unmerge);
5583+
} else {
5584+
LLT SrcNarrowTy = LLT::fixed_vector(NewElemCount, SrcTy.getElementType());
5585+
5586+
// Split the Src and Dst Reg into smaller registers
5587+
if (extractGCDType(SrcVRegs, DstTy, SrcNarrowTy, SrcReg) != SrcNarrowTy)
5588+
return UnableToLegalize;
5589+
}
55835590

55845591
// Build new smaller bitcast instructions
55855592
// Not supporting Leftover types for now but will have to

llvm/test/CodeGen/AArch64/bitcast.ll

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,31 @@ define <8 x i64> @bitcast_v16i32_v8i64(<16 x i32> %a, <16 x i32> %b){
617617
ret <8 x i64> %d
618618
}
619619

620+
define <8 x i32> @scalar_i128(<2 x i128> %a) {
621+
; CHECK-SD-LABEL: scalar_i128:
622+
; CHECK-SD: // %bb.0:
623+
; CHECK-SD-NEXT: fmov d1, x2
624+
; CHECK-SD-NEXT: fmov d0, x0
625+
; CHECK-SD-NEXT: mov v1.d[1], x3
626+
; CHECK-SD-NEXT: mov v0.d[1], x1
627+
; CHECK-SD-NEXT: add v0.4s, v0.4s, v0.4s
628+
; CHECK-SD-NEXT: add v1.4s, v1.4s, v1.4s
629+
; CHECK-SD-NEXT: ret
630+
;
631+
; CHECK-GI-LABEL: scalar_i128:
632+
; CHECK-GI: // %bb.0:
633+
; CHECK-GI-NEXT: mov v0.d[0], x0
634+
; CHECK-GI-NEXT: mov v1.d[0], x2
635+
; CHECK-GI-NEXT: mov v0.d[1], x1
636+
; CHECK-GI-NEXT: mov v1.d[1], x3
637+
; CHECK-GI-NEXT: add v0.4s, v0.4s, v0.4s
638+
; CHECK-GI-NEXT: add v1.4s, v1.4s, v1.4s
639+
; CHECK-GI-NEXT: ret
640+
%c = bitcast <2 x i128> %a to <8 x i32>
641+
%d = add <8 x i32> %c, %c
642+
ret <8 x i32> %d
643+
}
644+
620645
; ===== Vectors with Non-Pow 2 Widths =====
621646

622647
define <6 x i16> @bitcast_v3i32_v6i16(<3 x i32> %a, <3 x i32> %b){

0 commit comments

Comments
 (0)