-
-
Notifications
You must be signed in to change notification settings - Fork 72
✨ Add Constant Propagation #1845
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
789654d
e05e2fe
fc10555
fa877c6
d784d01
e1b6b37
59739f1
9dc386e
5653b9a
67d3c7c
95e3604
e01a8b9
798c514
baf731c
a43b158
7fd4f75
9c43526
18382b3
7a89811
cc5f15c
a682420
2c298bf
e3da07f
b3bf966
b2862e8
e9c66b3
13c046d
db8491e
f95eeb0
18cb1b0
fb70183
d785bdb
74edb2e
cc97cfd
26ca2ed
a15d2c1
233da3f
6af2a96
664abad
cf245b1
4ab38c1
57159ae
c966623
8d32188
edc59a2
cdfc8ed
de726cb
500b0d1
b67a26f
928f6c5
9b2397e
20b6580
3b430d4
ee2f941
f3cb1d7
e5ba050
afdb6b0
44d8c98
1ca77fa
10b21ed
f183f63
89da08c
2f0dbe6
31995a8
3750513
0da58cf
1c2a5a8
fce739b
3331f0c
7f1256b
3084ec4
615bbd4
9afaacd
43452ee
0fcf1e6
6b4f865
413585b
06c681f
4bd6f65
87ddcde
992c0f6
3954213
549e786
060c7c7
fca5829
dfb3c79
edbde78
24903c1
4c8b2bf
37df86d
515928d
9e5d051
2fc9805
eeec576
fa6667b
af69c0c
c77bb06
2cbc8ae
8b23135
e8b170d
e8dabcb
1607ddb
c3fd47c
3300fe6
056af2e
b3269eb
aecb3a0
fefdc7e
1a93171
d7bfb19
2cc0545
500ada9
9c47ebf
ab7ba5b
a0341a7
e0f9a98
d4690b1
32dde57
4e8463d
9f15fb1
af40f05
27e9da3
1819c07
eb0f2fb
99850ff
64619cc
0d440a2
ef60703
6397001
c527209
80c6b82
dd691d1
3ec5f72
22e02a9
aea9d47
cd1ff0a
e05c433
4c3f9cc
bf7b1af
ffe6293
774e859
e83acbd
a87875a
fb56ef0
74d198b
edd955c
4420939
b096acf
c26efd8
33b2498
a2252d0
536950f
a41cf5a
34ff5ad
be3bb9c
9e132b0
bf61d45
ef9bd3a
dd1ee75
a88b33e
cf1d023
8b6e347
34eefac
a46a201
d06dd5f
7e8d48f
17307b3
b373771
3d7164f
62e5ec6
5299761
3dc72e4
8494cf3
2e9bbc2
83b7eaa
0bfc8e4
c5fcd98
374f056
40d2fc6
776068f
24aa56a
fac19e0
158c32d
851fd22
29e36fc
76e6b50
12ee3f8
4b86a0b
1b94f3f
52062f0
1ed7b20
bb38f78
9b42fa9
dc21457
93446b3
a930830
22f705e
9bdaaa1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| /* | ||
| * Copyright (c) 2023 - 2026 Chair for Design Automation, TUM | ||
| * Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH | ||
| * All rights reserved. | ||
| * | ||
| * SPDX-License-Identifier: MIT | ||
| * | ||
| * Licensed under the MIT License | ||
| */ | ||
|
|
||
| #pragma once | ||
|
|
||
| #ifndef MQT_CORE_CLASSICALARITHOPERATION_H | ||
| #define MQT_CORE_CLASSICALARITHOPERATION_H | ||
|
|
||
| #include "mlir/Dialect/QCO/IR/QCOOps.h" | ||
| #include "mlir/Dialect/QCO/Utils/Drivers.h" | ||
|
|
||
| #include <mlir/Dialect/Arith/IR/Arith.h> | ||
| #include <mlir/IR/BuiltinTypes.h> | ||
| #include <mlir/IR/Operation.h> | ||
|
|
||
| #include <cmath> | ||
| #include <stdexcept> | ||
|
|
||
| /** | ||
| * This file provides information of available arith operations. It calculates | ||
| * the result of valid arith operations. Operations are only valid with one to | ||
| * two operands, not if they are applied to sequences. | ||
| */ | ||
| inline int64_t getArithIntegerOpResult(mlir::Operation* operation, | ||
| int64_t value1, int64_t value2 = 0, | ||
| int64_t value3 = 0) { | ||
|
|
||
| for (mlir::Value operand : operation->getOperands()) { | ||
| if (isa<mlir::VectorType>(operand.getType())) { | ||
| throw std::runtime_error( | ||
| "Constant propagation does not support vectors as classical types."); | ||
| } | ||
| } | ||
|
|
||
| return mlir::TypeSwitch<mlir::Operation*, int64_t>(operation) | ||
| .Case<mlir::arith::AddIOp>([&](auto) { return value1 + value2; }) | ||
| .Case<mlir::arith::AndIOp>([&](auto) { return value1 & value2; }) | ||
| .Case<mlir::arith::CeilDivSIOp>([&](auto) { | ||
| // Division that rounds to positive infinity | ||
| return ceil(1.0 * value1 / value2); | ||
| }) | ||
| .Case<mlir::arith::DivSIOp>([&](auto) { | ||
| // Division that rounds towards zero | ||
| return value1 / value2; | ||
| }) | ||
| .Case<mlir::arith::FloorDivSIOp>([&](auto) { | ||
| // Division that rounds to negative infinity | ||
| return floor(1.0 * value1 / value2); | ||
| }) | ||
| .Case<mlir::arith::MaxSIOp>( | ||
| [&](auto) { return value1 > value2 ? value1 : value2; }) | ||
| .Case<mlir::arith::MinSIOp>( | ||
| [&](auto) { return value1 < value2 ? value1 : value2; }) | ||
| .Case<mlir::arith::MulIOp>([&](auto) { return value1 * value2; }) | ||
| .Case<mlir::arith::OrIOp>([&](auto) { return value1 | value2; }) | ||
| .Case<mlir::arith::RemSIOp>( | ||
| [&](auto) { return remainder(value1, value2); }) | ||
| .Case<mlir::arith::ShLIOp>([&](auto) { return value1 << value2; }) | ||
| .Case<mlir::arith::ShRSIOp>([&](auto) { return value1 >> value2; }) | ||
| .Case<mlir::arith::SubIOp>([&](auto) { return value1 - value2; }) | ||
| .Case<mlir::arith::XOrIOp>([&](auto) { return value1 ^ value2; }) | ||
| .Case<mlir::arith::SelectOp>( | ||
| [&](auto) { return value1 == 0 ? value3 : value2; }) | ||
| .Default([&](auto) -> int64_t { | ||
| throw std::runtime_error("Unsupported integer operation in " | ||
| "mlir::qco::classicalarithoperation"); | ||
| }); | ||
| } | ||
|
|
||
| inline double getArithDoubleOpResult(mlir::Operation* operation, double value1, | ||
| double value2 = 0.0) { | ||
|
|
||
| for (mlir::Value operand : operation->getOperands()) { | ||
| if (isa<mlir::VectorType>(operand.getType())) { | ||
| throw std::runtime_error( | ||
| "Constant propagation does not support vectors as classical types."); | ||
| } | ||
| } | ||
|
|
||
| return mlir::TypeSwitch<mlir::Operation*, double>(operation) | ||
| .Case<mlir::arith::AddFOp>([&](auto) { return value1 + value2; }) | ||
| .Case<mlir::arith::DivFOp>([&](auto) { return value1 / value2; }) | ||
| .Case<mlir::arith::MaximumFOp>( | ||
| [&](auto) { return value1 > value2 ? value1 : value2; }) | ||
| .Case<mlir::arith::MaxNumFOp>( | ||
| [&](auto) { return value1 > value2 ? value1 : value2; }) | ||
| .Case<mlir::arith::MinimumFOp>( | ||
| [&](auto) { return value1 < value2 ? value1 : value2; }) | ||
| .Case<mlir::arith::MinNumFOp>( | ||
| [&](auto) { return value1 < value2 ? value1 : value2; }) | ||
| .Case<mlir::arith::MulFOp>([&](auto) { return value1 * value2; }) | ||
| .Case<mlir::arith::NegFOp>([&](auto) { return -value1; }) | ||
| .Case<mlir::arith::RemFOp>( | ||
| [&](auto) { return remainder(value1, value2); }) | ||
| .Case<mlir::arith::SubFOp>([&](auto) { return value1 - value2; }) | ||
| .Default([&](auto) -> double { | ||
| throw std::runtime_error("Unsupported floating-point operation in " | ||
| "mlir::qco::classicalarithoperation"); | ||
| }); | ||
| } | ||
|
Comment on lines
+31
to
+107
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🔴 Critical | 🏗️ Heavy lift 🧩 Analysis chain🌐 Web query:
💡 Result: The MLIR 'arith' dialect defines basic arithmetic operations that operate on scalars (integers or floating-point), as well as vectors and tensors of these types [1]. Unless otherwise stated, these operations use two's complement representation for integers and propagate poison values [1]. If any input is poison, the result is poison [1]. arith.remsi (Signed Integer Division Remainder) This operation performs a signed integer remainder [2][3]. It treats the leading bit as a sign bit (e.g., 6 % -2 = 0) [2][3]. Division by zero is undefined behavior [2][3]. For vector and tensor types, if any element is divided by zero, the behavior is undefined [2][3]. arith.remf (Floating-Point Remainder) This operation performs a floating-point remainder, with semantics matching the llvm.frem instruction [4]. The sign of the result always matches the sign of the dividend (the left-hand side operand) [4]. arith.ceildivsi (Signed Integer Ceil Division) This performs signed integer division rounded towards positive infinity (e.g., 7 / -2 = -3) [5]. arith.floordivsi (Signed Integer Floor Division) This performs signed integer division rounded towards negative infinity (e.g., 5 / -2 = -3) [5][6]. arith.maximumf (Floating-Point Maximum) Returns the maximum of two arguments, treating -0.0 as less than +0.0 [2][5]. If either argument is NaN, the result is NaN [2][5]. arith.maxnumf (Floating-Point Maximum) Returns the maximum of two arguments [2][5]. If the arguments are -0.0 and +0.0, the result is either value [2][5]. If one argument is NaN, the result is the other argument [2][5]. Note on Integer Bit Widths: These operations are polymorphic and accept integers of any bit width (e.g., i8, i16, i32, i64) as defined in the MLIR type system [1][2]. The specific behavior, such as two's complement arithmetic and overflow behavior, applies generically across these widths [1]. Note on Poison: Unless otherwise specified, all operations in the arith dialect propagate poison values, meaning that if any of the inputs are poison, the output is also poison [1]. For structured types (vector/tensor), this propagation occurs element-wise [1]. Citations:
🏁 Script executed: #!/bin/bash
set -euo pipefail
# Map the target header and nearby symbols.
ast-grep outline mlir/include/mlir/Dialect/QCO/Transforms/Optimizations/ConstantPropagation/ClassicalArithOperation.h --view expanded || true
echo
echo "=== File excerpt ==="
sed -n '1,220p' mlir/include/mlir/Dialect/QCO/Transforms/Optimizations/ConstantPropagation/ClassicalArithOperation.h
echo
echo "=== Call sites for helpers ==="
rg -n "getArith(Integer|Double)OpResult|maximumf|maxnumf|remsi|remf|ceildivsi|floordivsi" mlir -g '!**/build/**'Repository: munich-quantum-toolkit/core Length of output: 5551 Use MLIR folding/APInt/APFloat here instead of native C++ arithmetic.
🤖 Prompt for AI Agents |
||
|
|
||
| #endif // MQT_CORE_MQT_CORE_CLASSICALARITHOPERATION_H | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Fix the author attribution markup.
Line 16 is missing the closing
**, so the contributor attribution renders incorrectly.Proposed fix
📝 Committable suggestion
🤖 Prompt for AI Agents