Skip to content

Commit 7918d8e

Browse files
committed
FPInfo: MachineVerifier
FPInfo: MachineIRBuilder assertions
1 parent 5de13ed commit 7918d8e

File tree

3 files changed

+235
-61
lines changed

3 files changed

+235
-61
lines changed

llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ class MachineIRBuilder {
239239
unsigned getOpcodeForMerge(const DstOp &DstOp, ArrayRef<SrcOp> SrcOps) const;
240240

241241
protected:
242-
void validateTruncExt(const LLT Dst, const LLT Src, bool IsExtend);
242+
void validateTruncExt(const LLT Dst, const LLT Src, unsigned Opc);
243243

244244
void validateUnaryOp(const LLT Res, const LLT Op0);
245245
void validateBinaryOp(const LLT Res, const LLT Op0, const LLT Op1);

llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp

Lines changed: 95 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ void MachineIRBuilder::validateBinaryOp(const LLT Res, const LLT Op0,
194194

195195
void MachineIRBuilder::validateShiftOp(const LLT Res, const LLT Op0,
196196
const LLT Op1) {
197-
assert((Res.isScalar() || Res.isVector()) && "invalid operand type");
197+
assert((Res.isInteger() || Res.isIntegerVector()) && "invalid operand type");
198198
assert((Res == Op0) && "type mismatch");
199199
}
200200

@@ -203,7 +203,8 @@ MachineIRBuilder::buildPtrAdd(const DstOp &Res, const SrcOp &Op0,
203203
const SrcOp &Op1, std::optional<unsigned> Flags) {
204204
assert(Res.getLLTTy(*getMRI()).isPointerOrPointerVector() &&
205205
Res.getLLTTy(*getMRI()) == Op0.getLLTTy(*getMRI()) && "type mismatch");
206-
assert(Op1.getLLTTy(*getMRI()).getScalarType().isScalar() && "invalid offset type");
206+
assert(Op1.getLLTTy(*getMRI()).getScalarType().isInteger() &&
207+
"invalid offset type");
207208

208209
return buildInstr(TargetOpcode::G_PTR_ADD, {Res}, {Op0, Op1}, Flags);
209210
}
@@ -228,7 +229,7 @@ MachineInstrBuilder MachineIRBuilder::buildMaskLowPtrBits(const DstOp &Res,
228229
const SrcOp &Op0,
229230
uint32_t NumBits) {
230231
LLT PtrTy = Res.getLLTTy(*getMRI());
231-
LLT MaskTy = LLT::scalar(PtrTy.getSizeInBits());
232+
LLT MaskTy = LLT::integer(PtrTy.getSizeInBits());
232233
Register MaskReg = getMRI()->createGenericVirtualRegister(MaskTy);
233234
buildConstant(MaskReg, maskTrailingZeros<uint64_t>(NumBits));
234235
return buildPtrMask(Res, Op0, MaskReg);
@@ -355,7 +356,7 @@ MachineInstrBuilder MachineIRBuilder::buildFConstant(const DstOp &Res,
355356
== EltTy.getSizeInBits() &&
356357
"creating fconstant with the wrong size");
357358

358-
assert(!Ty.isPointer() && "invalid operand type");
359+
assert((Ty.isFloat() || Ty.isFloatVector()) && "invalid operand type");
359360

360361
assert(!Ty.isScalableVector() &&
361362
"unexpected scalable vector in buildFConstant");
@@ -412,7 +413,7 @@ MachineIRBuilder::buildConstantPtrAuth(const DstOp &Res,
412413

413414
MachineInstrBuilder MachineIRBuilder::buildBrCond(const SrcOp &Tst,
414415
MachineBasicBlock &Dest) {
415-
assert(Tst.getLLTTy(*getMRI()).isScalar() && "invalid operand type");
416+
assert(Tst.getLLTTy(*getMRI()).isInteger() && "invalid operand type");
416417

417418
auto MIB = buildInstr(TargetOpcode::G_BRCOND);
418419
Tst.addSrcToMIB(MIB);
@@ -459,7 +460,7 @@ MachineInstrBuilder MachineIRBuilder::buildLoadFromOffset(
459460
return buildLoad(Dst, BasePtr, *OffsetMMO);
460461

461462
LLT PtrTy = BasePtr.getLLTTy(*getMRI());
462-
LLT OffsetTy = LLT::scalar(PtrTy.getSizeInBits());
463+
LLT OffsetTy = LLT::integer(PtrTy.getSizeInBits());
463464
auto ConstOffset = buildConstant(OffsetTy, Offset);
464465
auto Ptr = buildPtrAdd(PtrTy, BasePtr, ConstOffset);
465466
return buildLoad(Dst, Ptr, *OffsetMMO);
@@ -550,10 +551,10 @@ MachineInstrBuilder MachineIRBuilder::buildExtOrTrunc(unsigned ExtOpc,
550551
assert((TargetOpcode::G_ANYEXT == ExtOpc || TargetOpcode::G_ZEXT == ExtOpc ||
551552
TargetOpcode::G_SEXT == ExtOpc) &&
552553
"Expecting Extending Opc");
553-
assert(Res.getLLTTy(*getMRI()).isScalar() ||
554-
Res.getLLTTy(*getMRI()).isVector());
555-
assert(Res.getLLTTy(*getMRI()).isScalar() ==
556-
Op.getLLTTy(*getMRI()).isScalar());
554+
assert(Res.getLLTTy(*getMRI()).isInteger() ||
555+
Res.getLLTTy(*getMRI()).isIntegerVector());
556+
assert(Res.getLLTTy(*getMRI()).isInteger() ==
557+
Op.getLLTTy(*getMRI()).isInteger());
557558

558559
unsigned Opcode = TargetOpcode::COPY;
559560
if (Res.getLLTTy(*getMRI()).getSizeInBits() >
@@ -1208,8 +1209,11 @@ MachineIRBuilder::buildBlockAddress(Register Res, const BlockAddress *BA) {
12081209
}
12091210

12101211
void MachineIRBuilder::validateTruncExt(const LLT DstTy, const LLT SrcTy,
1211-
bool IsExtend) {
1212+
unsigned Opc) {
12121213
#ifndef NDEBUG
1214+
bool IsExtend = Opc == TargetOpcode::G_SEXT || Opc == TargetOpcode::G_ZEXT ||
1215+
Opc == TargetOpcode::G_ANYEXT || Opc == TargetOpcode::G_FPEXT;
1216+
bool IsFP = Opc == TargetOpcode::G_FPEXT || Opc == TargetOpcode::G_FPTRUNC;
12131217
if (DstTy.isVector()) {
12141218
assert(SrcTy.isVector() && "mismatched cast between vector and non-vector");
12151219
assert(SrcTy.getElementCount() == DstTy.getElementCount() &&
@@ -1223,6 +1227,18 @@ void MachineIRBuilder::validateTruncExt(const LLT DstTy, const LLT SrcTy,
12231227
else
12241228
assert(TypeSize::isKnownLT(DstTy.getSizeInBits(), SrcTy.getSizeInBits()) &&
12251229
"invalid widening trunc");
1230+
1231+
if (IsFP) {
1232+
assert(DstTy.getScalarType().isFloat() &&
1233+
"fpext/fptrunc destinaton type must be float");
1234+
assert(SrcTy.getScalarType().isFloat() &&
1235+
"fpext/fptrunc source type must be float");
1236+
} else {
1237+
assert(!DstTy.getScalarType().isFloat() &&
1238+
"ext/trunc destinaton type must not be float");
1239+
assert(!SrcTy.getScalarType().isFloat() &&
1240+
"ext/trunc source type must not be float");
1241+
}
12261242
#endif
12271243
}
12281244

@@ -1284,11 +1300,16 @@ MachineIRBuilder::buildInstr(unsigned Opc, ArrayRef<DstOp> DstOps,
12841300
case TargetOpcode::G_USUBSAT:
12851301
case TargetOpcode::G_SSUBSAT: {
12861302
// All these are binary ops.
1303+
LLT DstTy = DstOps[0].getLLTTy(*getMRI());
1304+
LLT Src1Ty = SrcOps[0].getLLTTy(*getMRI());
1305+
LLT Src2Ty = SrcOps[1].getLLTTy(*getMRI());
1306+
assert(DstTy.getScalarType().isInteger() && "Invalid destination type");
1307+
assert((Src1Ty.getScalarType().isInteger() ||
1308+
Src2Ty.getScalarType().isIntegerVector()) &&
1309+
"Invalid source type");
12871310
assert(DstOps.size() == 1 && "Invalid Dst");
12881311
assert(SrcOps.size() == 2 && "Invalid Srcs");
1289-
validateBinaryOp(DstOps[0].getLLTTy(*getMRI()),
1290-
SrcOps[0].getLLTTy(*getMRI()),
1291-
SrcOps[1].getLLTTy(*getMRI()));
1312+
validateBinaryOp(DstTy, Src1Ty, Src2Ty);
12921313
break;
12931314
}
12941315
case TargetOpcode::G_SHL:
@@ -1306,17 +1327,13 @@ MachineIRBuilder::buildInstr(unsigned Opc, ArrayRef<DstOp> DstOps,
13061327
case TargetOpcode::G_SEXT:
13071328
case TargetOpcode::G_ZEXT:
13081329
case TargetOpcode::G_ANYEXT:
1309-
assert(DstOps.size() == 1 && "Invalid Dst");
1310-
assert(SrcOps.size() == 1 && "Invalid Srcs");
1311-
validateTruncExt(DstOps[0].getLLTTy(*getMRI()),
1312-
SrcOps[0].getLLTTy(*getMRI()), true);
1313-
break;
1330+
case TargetOpcode::G_FPEXT:
13141331
case TargetOpcode::G_TRUNC:
13151332
case TargetOpcode::G_FPTRUNC: {
13161333
assert(DstOps.size() == 1 && "Invalid Dst");
13171334
assert(SrcOps.size() == 1 && "Invalid Srcs");
13181335
validateTruncExt(DstOps[0].getLLTTy(*getMRI()),
1319-
SrcOps[0].getLLTTy(*getMRI()), false);
1336+
SrcOps[0].getLLTTy(*getMRI()), Opc);
13201337
break;
13211338
}
13221339
case TargetOpcode::G_BITCAST: {
@@ -1346,47 +1363,88 @@ MachineIRBuilder::buildInstr(unsigned Opc, ArrayRef<DstOp> DstOps,
13461363
}() && "Invalid predicate");
13471364
assert(SrcOps[1].getLLTTy(*getMRI()) == SrcOps[2].getLLTTy(*getMRI()) &&
13481365
"Type mismatch");
1366+
LLT Op0Ty = SrcOps[1].getLLTTy(*getMRI());
1367+
LLT Op1Ty = SrcOps[2].getLLTTy(*getMRI());
1368+
LLT DstTy = DstOps[0].getLLTTy(*getMRI());
13491369
assert([&]() -> bool {
1350-
LLT Op0Ty = SrcOps[1].getLLTTy(*getMRI());
1351-
LLT DstTy = DstOps[0].getLLTTy(*getMRI());
13521370
if (Op0Ty.isScalar() || Op0Ty.isPointer())
13531371
return DstTy.isScalar();
13541372
else
13551373
return DstTy.isVector() &&
13561374
DstTy.getElementCount() == Op0Ty.getElementCount();
13571375
}() && "Type Mismatch");
1376+
1377+
if (Opc == TargetOpcode::G_ICMP) {
1378+
assert(!Op0Ty.getScalarType().isFloat() &&
1379+
!Op1Ty.getScalarType().isFloat() &&
1380+
"G_ICMP operands cannot be float");
1381+
} else {
1382+
assert(Op0Ty.getScalarType().isFloat() &&
1383+
Op1Ty.getScalarType().isFloat() &&
1384+
"G_FCMP operands must be float");
1385+
}
13581386
break;
13591387
}
13601388
case TargetOpcode::G_UNMERGE_VALUES: {
13611389
assert(!DstOps.empty() && "Invalid trivial sequence");
13621390
assert(SrcOps.size() == 1 && "Invalid src for Unmerge");
1391+
1392+
LLT DstTy = DstOps[0].getLLTTy(*getMRI());
1393+
LLT SrcTy = SrcOps[0].getLLTTy(*getMRI());
1394+
unsigned NumDsts = DstOps.size();
13631395
assert(llvm::all_of(DstOps,
13641396
[&, this](const DstOp &Op) {
1365-
return Op.getLLTTy(*getMRI()) ==
1366-
DstOps[0].getLLTTy(*getMRI());
1397+
return Op.getLLTTy(*getMRI()) == DstTy;
13671398
}) &&
13681399
"type mismatch in output list");
1369-
assert((TypeSize::ScalarTy)DstOps.size() *
1370-
DstOps[0].getLLTTy(*getMRI()).getSizeInBits() ==
1371-
SrcOps[0].getLLTTy(*getMRI()).getSizeInBits() &&
1400+
assert(NumDsts * DstTy.getSizeInBits() == SrcTy.getSizeInBits() &&
13721401
"input operands do not cover output register");
1402+
1403+
if (DstTy.isVector()) {
1404+
assert(SrcTy.isVector() && "G_UNMERGE_VALUES source operand does not "
1405+
"match vector destination operands");
1406+
assert(SrcTy.getScalarType() == DstTy.getScalarType() ||
1407+
SrcTy.isPointerVector() ||
1408+
SrcTy.getSizeInBits() == NumDsts * DstTy.getSizeInBits() &&
1409+
"G_UNMERGE_VALUES source operand does "
1410+
"not match vector destination operands");
1411+
} else if (SrcTy.isFloatVector()) {
1412+
assert(DstTy.isFloat() &&
1413+
"G_UNMERGE_VALUES source vector element type does not match "
1414+
"scalar destination type");
1415+
1416+
assert(NumDsts == SrcTy.getNumElements() &&
1417+
"G_UNMERGE_VALUES number of destination operands has to match "
1418+
"the number of vector elements for float vectors");
1419+
} else {
1420+
assert(!SrcTy.isFloat() && !DstTy.isFloat() &&
1421+
"G_UNMERGE_VALUES is not supported for scalar float operands");
1422+
}
1423+
13731424
break;
13741425
}
13751426
case TargetOpcode::G_MERGE_VALUES: {
13761427
assert(SrcOps.size() >= 2 && "invalid trivial sequence");
13771428
assert(DstOps.size() == 1 && "Invalid Dst");
1429+
unsigned NumSrcs = SrcOps.size();
1430+
LLT SrcTy = SrcOps[0].getLLTTy(*getMRI());
13781431
assert(llvm::all_of(SrcOps,
13791432
[&, this](const SrcOp &Op) {
1380-
return Op.getLLTTy(*getMRI()) ==
1381-
SrcOps[0].getLLTTy(*getMRI());
1433+
return Op.getLLTTy(*getMRI()) == SrcTy;
13821434
}) &&
13831435
"type mismatch in input list");
1384-
assert((TypeSize::ScalarTy)SrcOps.size() *
1385-
SrcOps[0].getLLTTy(*getMRI()).getSizeInBits() ==
1386-
DstOps[0].getLLTTy(*getMRI()).getSizeInBits() &&
1436+
assert(llvm::all_of(SrcOps,
1437+
[&, this](const SrcOp &Op) {
1438+
return !Op.getLLTTy(*getMRI()).isFloat();
1439+
}) &&
1440+
"float types are not alowed in input list");
1441+
LLT DstTy = DstOps[0].getLLTTy(*getMRI());
1442+
assert(NumSrcs * SrcTy.getSizeInBits() == DstTy.getSizeInBits() &&
13871443
"input operands do not cover output register");
1388-
assert(!DstOps[0].getLLTTy(*getMRI()).isVector() &&
1444+
assert(!DstTy.isVector() &&
13891445
"vectors should be built with G_CONCAT_VECTOR or G_BUILD_VECTOR");
1446+
assert(!DstTy.isFloat() &&
1447+
"G_MERGE_VALUES float result types are not allowed");
13901448
break;
13911449
}
13921450
case TargetOpcode::G_EXTRACT_VECTOR_ELT: {
@@ -1438,8 +1496,10 @@ MachineIRBuilder::buildInstr(unsigned Opc, ArrayRef<DstOp> DstOps,
14381496
assert((!SrcOps.empty() || SrcOps.size() < 2) &&
14391497
"Must have at least 2 operands");
14401498
assert(DstOps.size() == 1 && "Invalid DstOps");
1441-
assert(DstOps[0].getLLTTy(*getMRI()).isVector() &&
1442-
"Res type must be a vector");
1499+
assert(DstOps[0].getLLTTy(*getMRI()).isIntegerVector() &&
1500+
"Res type must be a vector of integers");
1501+
assert(SrcOps[0].getLLTTy(*getMRI()).isInteger() &&
1502+
"Src type must be an integer");
14431503
assert(llvm::all_of(SrcOps,
14441504
[&, this](const SrcOp &Op) {
14451505
return Op.getLLTTy(*getMRI()) ==

0 commit comments

Comments
 (0)