Make getExpectedModelType more strict on integers

This commit teaches getExpectedModelType about the fact that various
bitwise operations are only allowed to have integer operands.

It also updates VMA, which uses getExpectedModelType, to take this
into account.
This commit is contained in:
Pietro Fezzardi
2023-04-13 15:54:32 +02:00
parent 118929b8fd
commit 56db9e6660
5 changed files with 142 additions and 53 deletions
+23 -21
View File
@@ -69,8 +69,14 @@ static ColorSet getAcceptedColors(FunctionMetadataCache &Cache,
// handling when there is no model.
if (not DeducedTypes.empty()) {
if (DeducedTypes.size() == 1)
return QTToColor(DeducedTypes.back());
if (DeducedTypes.size() == 1) {
ColorSet Result = QTToColor(DeducedTypes.back());
if (isUse(Content)
and getUse(Content)->get()->getType()->isIntegerTy(1))
Result.addColor(BOOLNESS);
return Result;
}
// There are cases in which we can associate to an LLVM value (typically
// an aggregate) more than one model type, e.g. for values returned by
@@ -164,27 +170,20 @@ static ColorSet getAcceptedColors(FunctionMetadataCache &Cache,
case Instruction::AShr:
if (IsContentInst or getOpNo(Content) == 0)
return SIGNEDNESS;
return SIGNEDNESS | NUMBERNESS;
if (getOpNo(Content) == 1)
return ~(FLOATNESS | POINTERNESS);
break;
case Instruction::LShr:
if (IsContentInst or getOpNo(Content) == 0)
// TODO: rule on first operand too strict?
return UNSIGNEDNESS;
return UNSIGNEDNESS | NUMBERNESS;
if (getOpNo(Content) == 1)
return ~(FLOATNESS | POINTERNESS);
break;
case Instruction::Shl:
if (IsContentInst)
return ~(FLOATNESS | POINTERNESS);
if (getOpNo(Content) == 0)
// TODO: rule on first operand too strict?
return (SIGNEDNESS | UNSIGNEDNESS | BOOLNESS);
if (getOpNo(Content) == 1)
return ~(FLOATNESS | POINTERNESS);
return (SIGNEDNESS | UNSIGNEDNESS | BOOLNESS | NUMBERNESS);
break;
case Instruction::Mul:
@@ -203,12 +202,10 @@ static ColorSet getAcceptedColors(FunctionMetadataCache &Cache,
return BOOLNESS;
break;
case Instruction::Trunc:
case Instruction::And:
case Instruction::Or:
case Instruction::Xor:
// TODO: Restrict more what can be accepted by bitwise operations?
return ~NUMBERNESS;
return NUMBERNESS | UNSIGNEDNESS | SIGNEDNESS | BOOLNESS;
break;
case Instruction::GetElementPtr:
@@ -372,7 +369,6 @@ static bool connect(TypeFlowNode *N1, TypeFlowNode *N2) {
break;
}
case Instruction::Mul:
case Instruction::Sub:
return AddBidirectionalEdge(UseNode,
ValNode,
@@ -393,13 +389,19 @@ static bool connect(TypeFlowNode *N1, TypeFlowNode *N2) {
return AddBidirectionalEdge(UseNode, ValNode, ~NUMBERNESS);
break;
case Instruction::Mul:
case Instruction::And:
case Instruction::Or:
case Instruction::Xor:
return AddBidirectionalEdge(UseNode,
ValNode,
~(FLOATNESS | POINTERNESS | NUMBERNESS));
break;
case Instruction::Xor: {
auto Colors = ~(FLOATNESS | POINTERNESS | NUMBERNESS);
if (not I->getType()->isIntegerTy(1))
Colors &= ~BOOLNESS;
return AddBidirectionalEdge(UseNode, ValNode, Colors);
} break;
// Freeze is transparent
case Instruction::Freeze:
return AddBidirectionalEdge(UseNode, ValNode, ALL_COLORS);
}
if (auto *Call = llvm::dyn_cast<CallInst>(I)) {