@@ -862,6 +862,13 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
862862 .legalForCartesianProduct ({s32, v2s16, v4s8})
863863 .legalForCartesianProduct ({s64, v8s8, v4s16, v2s32})
864864 .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+ })
865872 .lowerIf ([=](const LegalityQuery &Query) {
866873 return Query.Types [0 ].isVector () != Query.Types [1 ].isVector ();
867874 })
@@ -1406,11 +1413,28 @@ bool AArch64LegalizerInfo::legalizeCustom(
14061413 return Helper.lowerAbsToCNeg (MI);
14071414 case TargetOpcode::G_ICMP:
14081415 return legalizeICMP (MI, MRI, MIRBuilder);
1416+ case TargetOpcode::G_BITCAST:
1417+ return legalizeBitcast (MI, Helper);
14091418 }
14101419
14111420 llvm_unreachable (" expected switch to return" );
14121421}
14131422
1423+ bool AArch64LegalizerInfo::legalizeBitcast (MachineInstr &MI,
1424+ LegalizerHelper &Helper) const {
1425+ assert (MI.getOpcode () == TargetOpcode::G_BITCAST && " Unexpected opcode" );
1426+ auto [DstReg, DstTy, SrcReg, SrcTy] = MI.getFirst2RegLLTs ();
1427+ // We're trying to handle casts from i1 vectors to scalars but reloading from
1428+ // stack.
1429+ if (!DstTy.isScalar () || !SrcTy.isVector () ||
1430+ SrcTy.getElementType () != LLT::scalar (1 ))
1431+ return false ;
1432+
1433+ Helper.createStackStoreLoad (DstReg, SrcReg);
1434+ MI.eraseFromParent ();
1435+ return true ;
1436+ }
1437+
14141438bool AArch64LegalizerInfo::legalizeFunnelShift (MachineInstr &MI,
14151439 MachineRegisterInfo &MRI,
14161440 MachineIRBuilder &MIRBuilder,
0 commit comments