Skip to content

Commit 5a037ba

Browse files
committed
[𝘀𝗽𝗿] changes to main this commit is based on
Created using spr 1.3.5 [skip ci]
1 parent 2dfe1b4 commit 5a037ba

File tree

6 files changed

+113
-3
lines changed

6 files changed

+113
-3
lines changed

llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,10 @@ class LegalizerHelper {
297297
MachineInstrBuilder createStackTemporary(TypeSize Bytes, Align Alignment,
298298
MachinePointerInfo &PtrInfo);
299299

300+
/// Create a store of \p Val to a stack temporary and return a load of the
301+
/// same value as type \p DestVT.
302+
MachineInstrBuilder createStackStoreLoad(Register Val, LLT DstTy);
303+
300304
/// Get a pointer to vector element \p Index located in memory for a vector of
301305
/// type \p VecTy starting at a base address of \p VecPtr. If \p Index is out
302306
/// of bounds the returned pointer is unspecified, but will be within the

llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
2323
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
2424
#include "llvm/CodeGen/GlobalISel/Utils.h"
25+
#include "llvm/CodeGen/LowLevelTypeUtils.h"
2526
#include "llvm/CodeGen/MachineConstantPool.h"
2627
#include "llvm/CodeGen/MachineFrameInfo.h"
2728
#include "llvm/CodeGen/MachineRegisterInfo.h"
@@ -3022,8 +3023,18 @@ LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) {
30223023
return UnableToLegalize;
30233024

30243025
LLT Ty = MRI.getType(MI.getOperand(0).getReg());
3025-
if (!Ty.isScalar())
3026-
return UnableToLegalize;
3026+
if (!Ty.isScalar()) {
3027+
// We need to widen the vector element type.
3028+
Observer.changingInstr(MI);
3029+
widenScalarSrc(MI, WideTy, 0, TargetOpcode::G_ANYEXT);
3030+
// We also need to adjust the MMO to turn this into a truncating store.
3031+
MachineMemOperand &MMO = **MI.memoperands_begin();
3032+
MachineFunction &MF = MIRBuilder.getMF();
3033+
auto *NewMMO = MF.getMachineMemOperand(&MMO, MMO.getPointerInfo(), Ty);
3034+
MI.setMemRefs(MF, {NewMMO});
3035+
Observer.changedInstr(MI);
3036+
return Legalized;
3037+
}
30273038

30283039
Observer.changingInstr(MI);
30293040

@@ -4653,6 +4664,20 @@ LegalizerHelper::createStackTemporary(TypeSize Bytes, Align Alignment,
46534664
return MIRBuilder.buildFrameIndex(FramePtrTy, FrameIdx);
46544665
}
46554666

4667+
MachineInstrBuilder LegalizerHelper::createStackStoreLoad(Register Val,
4668+
LLT DstTy) {
4669+
LLT SrcTy = MRI.getType(Val);
4670+
Align StackTypeAlign = getStackTemporaryAlignment(SrcTy);
4671+
MachinePointerInfo PtrInfo;
4672+
auto StackTemp =
4673+
createStackTemporary(SrcTy.getSizeInBytes(), StackTypeAlign, PtrInfo);
4674+
4675+
MIRBuilder.buildStore(Val, StackTemp, PtrInfo, StackTypeAlign);
4676+
return MIRBuilder.buildLoad(
4677+
DstTy, StackTemp, PtrInfo,
4678+
std::min(StackTypeAlign, getStackTemporaryAlignment(DstTy)));
4679+
}
4680+
46564681
static Register clampVectorIndex(MachineIRBuilder &B, Register IdxReg,
46574682
LLT VecTy) {
46584683
LLT IdxTy = B.getMRI()->getType(IdxReg);

llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,7 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
454454
{nxv2s64, p0, nxv2s64, 8},
455455
})
456456
.clampScalar(0, s8, s64)
457+
.minScalarOrElt(0, s8)
457458
.lowerIf([=](const LegalityQuery &Query) {
458459
return Query.Types[0].isScalar() &&
459460
Query.Types[0] != Query.MMODescrs[0].MemoryTy;
@@ -861,6 +862,13 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
861862
.legalForCartesianProduct({s32, v2s16, v4s8})
862863
.legalForCartesianProduct({s64, v8s8, v4s16, v2s32})
863864
.legalForCartesianProduct({s128, v16s8, v8s16, v4s32, v2s64, v2p0})
865+
.customIf([=](const LegalityQuery &Query) {
866+
// Handle casts from i1 vectors to scalars.
867+
LLT DstTy = Query.Types[0];
868+
LLT SrcTy = Query.Types[1];
869+
return DstTy.isScalar() && SrcTy.isVector() &&
870+
SrcTy.getScalarSizeInBits() == 1;
871+
})
864872
.lowerIf([=](const LegalityQuery &Query) {
865873
return Query.Types[0].isVector() != Query.Types[1].isVector();
866874
})
@@ -1404,11 +1412,29 @@ bool AArch64LegalizerInfo::legalizeCustom(
14041412
return Helper.lowerAbsToCNeg(MI);
14051413
case TargetOpcode::G_ICMP:
14061414
return legalizeICMP(MI, MRI, MIRBuilder);
1415+
case TargetOpcode::G_BITCAST:
1416+
return legalizeBitcast(MI, Helper);
14071417
}
14081418

14091419
llvm_unreachable("expected switch to return");
14101420
}
14111421

1422+
bool AArch64LegalizerInfo::legalizeBitcast(MachineInstr &MI,
1423+
LegalizerHelper &Helper) const {
1424+
assert(MI.getOpcode() == TargetOpcode::G_BITCAST && "Unexpected opcode");
1425+
auto [DstReg, DstTy, SrcReg, SrcTy] = MI.getFirst2RegLLTs();
1426+
// We're trying to handle casts from i1 vectors to scalars but reloading from
1427+
// stack.
1428+
if (!DstTy.isScalar() || !SrcTy.isVector() ||
1429+
SrcTy.getElementType() != LLT::scalar(1))
1430+
return false;
1431+
1432+
auto Load = Helper.createStackStoreLoad(SrcReg, DstTy);
1433+
Helper.MIRBuilder.buildCopy(DstReg, Load.getReg(0));
1434+
MI.eraseFromParent();
1435+
return true;
1436+
}
1437+
14121438
bool AArch64LegalizerInfo::legalizeFunnelShift(MachineInstr &MI,
14131439
MachineRegisterInfo &MRI,
14141440
MachineIRBuilder &MIRBuilder,

llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class AArch64LegalizerInfo : public LegalizerInfo {
6666
LegalizerHelper &Helper) const;
6767
bool legalizeDynStackAlloc(MachineInstr &MI, LegalizerHelper &Helper) const;
6868
bool legalizePrefetch(MachineInstr &MI, LegalizerHelper &Helper) const;
69+
bool legalizeBitcast(MachineInstr &MI, LegalizerHelper &Helper) const;
6970
const AArch64Subtarget *ST;
7071
};
7172
} // End llvm namespace.

llvm/test/CodeGen/AArch64/GlobalISel/legalize-bitcast.mir

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4
2-
# RUN: llc -mtriple=aarch64 -run-pass=legalizer -global-isel-abort=1 %s -o - | FileCheck %s
2+
# RUN: llc -mtriple=aarch64 -run-pass=legalizer -global-isel-abort=2 %s -o - | FileCheck %s
33
---
44
name: scalar_to_oversize_vector
55
tracksRegLiveness: true
@@ -48,3 +48,25 @@ body: |
4848
G_BR %bb.2
4949
5050
...
51+
# This test currently is expected to fall back after reaching truncstore of <8 x s8> as <8 x s1>.
52+
---
53+
name: boolean_vector_to_scalar
54+
tracksRegLiveness: true
55+
body: |
56+
bb.1:
57+
; CHECK-LABEL: name: boolean_vector_to_scalar
58+
; CHECK: %vec:_(<8 x s1>) = G_IMPLICIT_DEF
59+
; CHECK-NEXT: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0
60+
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(<8 x s8>) = G_ANYEXT %vec(<8 x s1>)
61+
; CHECK-NEXT: G_STORE [[ANYEXT]](<8 x s8>), [[FRAME_INDEX]](p0) :: (store (<8 x s1>) into %stack.0)
62+
; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[FRAME_INDEX]](p0) :: (load (s8) from %stack.0)
63+
; CHECK-NEXT: %bc:_(s8) = COPY [[LOAD]](s8)
64+
; CHECK-NEXT: %ext:_(s32) = G_ANYEXT %bc(s8)
65+
; CHECK-NEXT: $w0 = COPY %ext(s32)
66+
; CHECK-NEXT: RET_ReallyLR implicit $w0
67+
%vec:_(<8 x s1>) = G_IMPLICIT_DEF
68+
%bc:_(s8) = G_BITCAST %vec(<8 x s1>)
69+
%ext:_(s32) = G_ANYEXT %bc(s8)
70+
$w0 = COPY %ext(s32)
71+
RET_ReallyLR implicit $w0
72+
...
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
2+
# RUN: llc -O0 -mtriple=aarch64 -run-pass=legalizer -global-isel-abort=2 %s -o - | FileCheck %s
3+
# This test currently is expected to fall back after reaching truncstore of <8 x s8> as <8 x s1>.
4+
---
5+
name: store_8xs1
6+
tracksRegLiveness: true
7+
body: |
8+
bb.1:
9+
liveins: $q0, $q1, $x0
10+
; CHECK-LABEL: name: store_8xs1
11+
; CHECK: liveins: $q0, $q1, $x0
12+
; CHECK-NEXT: {{ $}}
13+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0
14+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<4 x s32>) = COPY $q1
15+
; CHECK-NEXT: %ptr:_(p0) = COPY $x0
16+
; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<8 x s32>) = G_CONCAT_VECTORS [[COPY]](<4 x s32>), [[COPY1]](<4 x s32>)
17+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
18+
; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<8 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32)
19+
; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(<8 x s1>) = G_ICMP intpred(slt), [[CONCAT_VECTORS]](<8 x s32>), [[BUILD_VECTOR]]
20+
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(<8 x s8>) = G_ANYEXT [[ICMP]](<8 x s1>)
21+
; CHECK-NEXT: G_STORE [[ANYEXT]](<8 x s8>), %ptr(p0) :: (store (<8 x s1>))
22+
; CHECK-NEXT: RET_ReallyLR
23+
%1:_(<4 x s32>) = COPY $q0
24+
%2:_(<4 x s32>) = COPY $q1
25+
%ptr:_(p0) = COPY $x0
26+
%0:_(<8 x s32>) = G_CONCAT_VECTORS %1(<4 x s32>), %2(<4 x s32>)
27+
%4:_(s32) = G_CONSTANT i32 0
28+
%3:_(<8 x s32>) = G_BUILD_VECTOR %4(s32), %4(s32), %4(s32), %4(s32), %4(s32), %4(s32), %4(s32), %4(s32)
29+
%5:_(<8 x s1>) = G_ICMP intpred(slt), %0(<8 x s32>), %3
30+
G_STORE %5(<8 x s1>), %ptr(p0) :: (store (<8 x s1>))
31+
RET_ReallyLR
32+
...

0 commit comments

Comments
 (0)