aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Support/FileCheck.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Support/FileCheck.cpp')
-rw-r--r--llvm/lib/Support/FileCheck.cpp54
1 files changed, 54 insertions, 0 deletions
diff --git a/llvm/lib/Support/FileCheck.cpp b/llvm/lib/Support/FileCheck.cpp
index fe4d641..d0e79c6 100644
--- a/llvm/lib/Support/FileCheck.cpp
+++ b/llvm/lib/Support/FileCheck.cpp
@@ -230,6 +230,58 @@ Expected<ExpressionValue> llvm::operator-(const ExpressionValue &LeftOperand,
}
}
+Expected<ExpressionValue> llvm::operator*(const ExpressionValue &LeftOperand,
+ const ExpressionValue &RightOperand) {
+ // -A * -B == A * B
+ if (LeftOperand.isNegative() && RightOperand.isNegative())
+ return LeftOperand.getAbsolute() * RightOperand.getAbsolute();
+
+ // A * -B == -B * A
+ if (RightOperand.isNegative())
+ return RightOperand * LeftOperand;
+
+ assert(!RightOperand.isNegative() && "Unexpected negative operand!");
+
+ // Result will be negative and can underflow.
+ if (LeftOperand.isNegative()) {
+ auto Result = LeftOperand.getAbsolute() * RightOperand.getAbsolute();
+ if (!Result)
+ return Result;
+
+ return ExpressionValue(0) - *Result;
+ }
+
+ // Result will be positive and can overflow.
+ uint64_t LeftValue = cantFail(LeftOperand.getUnsignedValue());
+ uint64_t RightValue = cantFail(RightOperand.getUnsignedValue());
+ Optional<uint64_t> Result =
+ checkedMulUnsigned<uint64_t>(LeftValue, RightValue);
+ if (!Result)
+ return make_error<OverflowError>();
+
+ return ExpressionValue(*Result);
+}
+
+Expected<ExpressionValue> llvm::operator/(const ExpressionValue &LeftOperand,
+ const ExpressionValue &RightOperand) {
+ // -A / -B == A / B
+ if (LeftOperand.isNegative() && RightOperand.isNegative())
+ return LeftOperand.getAbsolute() / RightOperand.getAbsolute();
+
+ // Check for divide by zero.
+ if (RightOperand == ExpressionValue(0))
+ return make_error<OverflowError>();
+
+ // Result will be negative and can underflow.
+ if (LeftOperand.isNegative() || RightOperand.isNegative())
+ return ExpressionValue(0) -
+ cantFail(LeftOperand.getAbsolute() / RightOperand.getAbsolute());
+
+ uint64_t LeftValue = cantFail(LeftOperand.getUnsignedValue());
+ uint64_t RightValue = cantFail(RightOperand.getUnsignedValue());
+ return ExpressionValue(LeftValue / RightValue);
+}
+
Expected<ExpressionValue> llvm::max(const ExpressionValue &LeftOperand,
const ExpressionValue &RightOperand) {
if (LeftOperand.isNegative() && RightOperand.isNegative()) {
@@ -592,8 +644,10 @@ Pattern::parseCallExpr(StringRef &Expr, StringRef FuncName,
auto OptFunc = StringSwitch<Optional<binop_eval_t>>(FuncName)
.Case("add", operator+)
+ .Case("div", operator/)
.Case("max", max)
.Case("min", min)
+ .Case("mul", operator*)
.Case("sub", operator-)
.Default(None);