Skip to content

Commit

Permalink
Allow shifts with constant signed positive amounts (p4lang#3303)
Browse files Browse the repository at this point in the history
* Allow shifts with constant signed positive amounts
Signed-off-by: Mihai Budiu <[email protected]>
  • Loading branch information
Mihai Budiu authored and github-sajan committed May 26, 2022
1 parent 627ca2f commit f5ee442
Show file tree
Hide file tree
Showing 12 changed files with 101 additions and 21 deletions.
1 change: 0 additions & 1 deletion backends/bmv2/common/lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@ const IR::Node* LowerExpressions::postorder(IR::Concat* expression) {
BUG_CHECK(resulttype->is<IR::Type_Bits>(), "%1%: expected a bitstring got a %2%",
expression->right, type);
unsigned sizeofb = type->to<IR::Type_Bits>()->size;
unsigned sizeofresult = resulttype->to<IR::Type_Bits>()->size;
auto cast0 = new IR::Cast(expression->left->srcInfo, resulttype, expression->left);
auto cast1 = new IR::Cast(expression->right->srcInfo, resulttype, expression->right);

Expand Down
6 changes: 0 additions & 6 deletions frontends/common/constantFolding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -777,12 +777,6 @@ const IR::Node* DoConstantFolding::shift(const IR::Operation_Binary* e) {
::error(ErrorType::ERR_INVALID, "%1%: Shifts with negative amounts are not permitted", e);
return e;
}
if (auto crTypeBits = cr->type->to<IR::Type_Bits>()) {
if (crTypeBits->isSigned) {
::error(ErrorType::ERR_EXPECTED, "%1%: shift amounts cannot be signed", right);
return e;
}
}

if (cr->value == 0) {
// ::warning("%1% with zero", e);
Expand Down
17 changes: 15 additions & 2 deletions frontends/p4/typeChecking/typeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2301,8 +2301,7 @@ const IR::Node* TypeInference::shift(const IR::Operation_Binary* expression) {
return expression;
}
auto lt = ltype->to<IR::Type_Bits>();
if (expression->right->is<IR::Constant>()) {
auto cst = expression->right->to<IR::Constant>();
if (auto cst = expression->right->to<IR::Constant>()) {
if (!cst->fitsInt()) {
typeError("Shift amount too large: %1%", cst);
return expression;
Expand All @@ -2315,6 +2314,20 @@ const IR::Node* TypeInference::shift(const IR::Operation_Binary* expression) {
if (lt != nullptr && shift >= lt->size)
warn(ErrorType::WARN_OVERFLOW, "%1%: shifting value with %2% bits by %3%",
expression, lt->size, shift);
// If the amount is signed but positive, make it unsigned
if (auto bt = rtype->to<IR::Type_Bits>()) {
if (bt->isSigned) {
rtype = new IR::Type_Bits(rtype->srcInfo, bt->width_bits(), false);
auto amt = new IR::Constant(cst->srcInfo, rtype, cst->value, cst->base);
if (expression->is<IR::Shl>()) {
expression = new IR::Shl(expression->srcInfo, expression->left, amt);
} else {
expression = new IR::Shr(expression->srcInfo, expression->left, amt);
}
setCompileTimeConstant(expression->right);
setType(expression->right, rtype);
}
}
}

if (rtype->is<IR::Type_Bits>() && rtype->to<IR::Type_Bits>()->isSigned) {
Expand Down
5 changes: 0 additions & 5 deletions testdata/p4_16_errors/issue2332-1.p4

This file was deleted.

4 changes: 0 additions & 4 deletions testdata/p4_16_errors_outputs/issue2332-1.p4

This file was deleted.

3 changes: 0 additions & 3 deletions testdata/p4_16_errors_outputs/issue2332-1.p4-stderr

This file was deleted.

19 changes: 19 additions & 0 deletions testdata/p4_16_samples/issue3287.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include <core.p4>

bit<4> func(in bit<4> l)
{
const int<6> tt = 1;
return l << tt;
}

parser p(out bit<4> result) {
state start {
result = func(1);
transition accept;
}
}

parser P(out bit<4> r);
package top(P p);

top(p()) main;
17 changes: 17 additions & 0 deletions testdata/p4_16_samples_outputs/issue3287-first.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include <core.p4>

bit<4> func(in bit<4> l) {
const int<6> tt = 6s1;
return l << 6w1;
}
parser p(out bit<4> result) {
state start {
result = func(4w1);
transition accept;
}
}

parser P(out bit<4> r);
package top(P p);
top(p()) main;

20 changes: 20 additions & 0 deletions testdata/p4_16_samples_outputs/issue3287-frontend.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include <core.p4>

parser p(out bit<4> result) {
@name("p.l_0") bit<4> l;
@name("p.hasReturned") bool hasReturned;
@name("p.retval") bit<4> retval;
state start {
l = 4w1;
hasReturned = false;
hasReturned = true;
retval = l << 6w1;
result = retval;
transition accept;
}
}

parser P(out bit<4> r);
package top(P p);
top(p()) main;

13 changes: 13 additions & 0 deletions testdata/p4_16_samples_outputs/issue3287-midend.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include <core.p4>

parser p(out bit<4> result) {
state start {
result = 4w2;
transition accept;
}
}

parser P(out bit<4> r);
package top(P p);
top(p()) main;

17 changes: 17 additions & 0 deletions testdata/p4_16_samples_outputs/issue3287.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include <core.p4>

bit<4> func(in bit<4> l) {
const int<6> tt = 1;
return l << tt;
}
parser p(out bit<4> result) {
state start {
result = func(1);
transition accept;
}
}

parser P(out bit<4> r);
package top(P p);
top(p()) main;

Empty file.

0 comments on commit f5ee442

Please sign in to comment.