1212#include " lib/Kernel/AbstractValue.h"
1313#include " lib/Kernel/ArithmeticDag.h"
1414#include " lib/Kernel/EvalVisitor.h"
15+ #include " lib/Utils/RotationUtils.h"
1516#include " llvm/include/llvm/Support/ErrorHandling.h" // from @llvm-project
1617
1718#define DEBUG_TYPE " rotation-analysis"
@@ -22,6 +23,7 @@ namespace heir {
2223using kernel::ArithmeticDagNode;
2324using kernel::DagType;
2425using kernel::EvalResults;
26+ using kernel::LeftRotateBulkNode;
2527using kernel::LeftRotateNode;
2628using kernel::LiteralValue;
2729using kernel::VariableNode;
@@ -38,15 +40,33 @@ EvalResults RotationEvalVisitor::operator()(
3840 auto evaluatedShift = this ->process (node.shift )[0 ];
3941 int amount = std::get<int >(evaluatedShift.get ());
4042
41- // Normalize amount to be in [0, dim)
42- amount = ((amount % dim) + dim) % dim;
43+ amount = normalizeRotation (amount, dim);
4344 evaluatedShifts.insert (amount);
4445
4546 // We don't need to rotate the values for rotation analysis. We just return
4647 // the operand as-is to keep the IR connected.
4748 return {operand};
4849}
4950
51+ EvalResults RotationEvalVisitor::operator ()(
52+ const LeftRotateBulkNode<LiteralValue>& node) {
53+ auto operand = this ->process (node.operand )[0 ];
54+ auto shape = operand.getShape ();
55+ assert (!shape.empty () && " rotate operand must be a tensor" );
56+ auto dim = shape.back ();
57+
58+ for (const auto & shiftNode : node.shifts ) {
59+ auto evaluatedShift = this ->process (shiftNode)[0 ];
60+ int amount = std::get<int >(evaluatedShift.get ());
61+ amount = normalizeRotation (amount, dim);
62+ evaluatedShifts.insert (amount);
63+ }
64+
65+ // We don't need to rotate the values for rotation analysis. We just return
66+ // the operand as-is to keep the IR connected.
67+ return {operand};
68+ }
69+
5070EvalResults RotationEvalVisitor::operator ()(
5171 const VariableNode<LiteralValue>& node) {
5272 if (node.value .has_value ()) {
0 commit comments