add support for llvm.bitreverse
MODIFY
ir/instr.cpp
ir/instr.cpp
@@ -253,6 +253,7 @@ expr BinOp::getTypeConstraints(const Function &f) const {
void UnaryOp::print(ostream &os) const {
const char *str = nullptr;
switch (op) {
+ case BitReverse: str = "bitreverse "; break;
case Ctpop: str = "ctpop "; break;
}
@@ -264,6 +265,9 @@ StateValue UnaryOp::toSMT(State &s) const {
expr newval;
switch (op) {
+ case BitReverse:
+ newval = v.bitreverse();
+ break;
case Ctpop:
newval = v.ctpop();
break;

MODIFY
ir/instr.h
ir/instr.h
@@ -44,7 +44,7 @@ public:
class UnaryOp final : public Instr {
public:
- enum Op { Ctpop };
+ enum Op { BitReverse, Ctpop };
private:
Value &val;

MODIFY
smt/expr.cpp
smt/expr.cpp
@@ -523,6 +523,18 @@ expr expr::lshr_exact(const expr &rhs) const {
return (lshr(rhs) << rhs) == *this;
}
+expr expr::bitreverse() const {
+ C();
+ auto nbits = bits();
+
+ expr res = extract(0, 0);
+ for (unsigned i = 1; i < nbits; i++) {
+ res = res.concat(extract(i, i));
+ }
+
+ return res;
+}
+
expr expr::cttz() const {
C();
auto nbits = bits();

MODIFY
smt/expr.h
smt/expr.h
@@ -129,6 +129,7 @@ public:
expr ashr_exact(const expr &rhs) const;
expr lshr_exact(const expr &rhs) const;
+ expr bitreverse() const;
expr cttz() const;
expr ctlz() const;
expr ctpop() const;

ADD
tests/unit/bitreverse.opt
+Name: bitreverse constant
+%a = bitreverse i8 32
+ =>
+%a = 4
+
+Name: bitreverse constant1
+%a = bitreverse i16 4352
+ =>
+%a = 136
+
+Name: bitreverse constant2
+%a = bitreverse i8 1
+ =>
+%a = 128
+
+Name: bitreverse constant3
+%a = bitreverse i8 129
+ =>
+%a = 129

MODIFY
tools/alive_lexer.re
tools/alive_lexer.re
@@ -189,6 +189,7 @@ re2c:yyfill:check = 0;
"ugt" { return UGT; }
"freeze" { return FREEZE; }
"ret" { return RETURN; }
+"bitreverse" { return BITREVERSE; }
"cttz" { return CTTZ; }
"ctlz" { return CTLZ; }
"ctpop" { return CTPOP; }

MODIFY
tools/alive_parser.cpp
tools/alive_parser.cpp
@@ -410,6 +410,7 @@ static unique_ptr<Instr> parse_binop(string_view name, token op_token) {
static unique_ptr<Instr> parse_unaryop(string_view name, token op_token) {
UnaryOp::Op op;
switch (op_token) {
+ case BITREVERSE: op = UnaryOp::BitReverse; break;
case CTPOP: op = UnaryOp::Ctpop; break;
default:
UNREACHABLE();
@@ -516,6 +517,7 @@ static unique_ptr<Instr> parse_instr(string_view name) {
case CTTZ:
case CTLZ:
return parse_binop(name, t);
+ case BITREVERSE:
case CTPOP:
return parse_unaryop(name, t);
case SEXT:

MODIFY
tools/tokens.h
tools/tokens.h
@@ -7,6 +7,7 @@ TOKEN(AND)
TOKEN(ARROW)
TOKEN(ASHR)
TOKEN(BAND)
+TOKEN(BITREVERSE)
TOKEN(BOR)
TOKEN(COMMA)
TOKEN(CONSTANT)

MODIFY
tv/tv.cpp
tv/tv.cpp
@@ -289,6 +289,11 @@ public:
RETURN_IDENTIFIER(make_unique<BinOp>(*ty, value_name(i), *a, *b,
BinOp::Ctlz));
}
+ case llvm::Intrinsic::bitreverse:
+ {
+ PARSE_UNOP();
+ RETURN_IDENTIFIER(make_unique<UnaryOp>(*ty, value_name(i), *val, UnaryOp::BitReverse));
+ }
case llvm::Intrinsic::ctpop:
{
PARSE_UNOP();

add support for llvm.bitreverse

https://llvm.org/docs/LangRef.html#llvm-bitreverse-intrinsics