aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Support/FileCheck.cpp
diff options
context:
space:
mode:
authorPaul Walker <paul.walker@arm.com>2020-06-01 10:09:58 +0000
committerPaul Walker <paul.walker@arm.com>2020-06-17 09:39:17 +0000
commit95db1e7fb9292daf70fedf02b5efafeabf3ea33e (patch)
treec34921c9fce8970aebab803357bad61d4ebf7d94 /llvm/lib/Support/FileCheck.cpp
parent16ad6eeb94ff0619288fb9b3a2287076d5f32ae1 (diff)
downloadllvm-95db1e7fb9292daf70fedf02b5efafeabf3ea33e.zip
llvm-95db1e7fb9292daf70fedf02b5efafeabf3ea33e.tar.gz
llvm-95db1e7fb9292daf70fedf02b5efafeabf3ea33e.tar.bz2
[FileCheck] Implement * and / operators for ExpressionValue.
Subscribers: arichardson, hiraditya, thopre, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D80915
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);