Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions ir/instr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ void BinOp::print(ostream &os) const {
case Abs: str = "abs "; break;
case UCmp: str = "ucmp "; break;
case SCmp: str = "scmp "; break;
case Clmul: str = "clmul "; break;
}

os << getName() << " = " << str;
Expand Down Expand Up @@ -473,6 +474,11 @@ StateValue BinOp::toSMT(State &s) const {
ap && bp};
};
break;
case Clmul:
fn = [&](auto &a, auto &ap, auto &b, auto &bp) -> StateValue {
return {a.clmul(b), ap && bp};
};
break;
}

function<pair<StateValue,StateValue>(const expr&, const expr&, const expr&,
Expand Down
2 changes: 1 addition & 1 deletion ir/instr.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class BinOp final : public Instr {
SAdd_Overflow, UAdd_Overflow, SSub_Overflow, USub_Overflow,
SMul_Overflow, UMul_Overflow,
And, Or, Xor, Cttz, Ctlz, UMin, UMax, SMin, SMax, Abs,
UCmp, SCmp };
UCmp, SCmp, Clmul };
enum Flags { None = 0, NSW = 1 << 0, NUW = 1 << 1, Exact = 1 << 2, Disjoint = 1 << 3 };

private:
Expand Down
4 changes: 3 additions & 1 deletion llvm_util/llvm2alive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -840,7 +840,8 @@ class llvm2alive_ : public llvm::InstVisitor<llvm2alive_, unique_ptr<Instr>> {
case llvm::Intrinsic::smax:
case llvm::Intrinsic::abs:
case llvm::Intrinsic::ucmp:
case llvm::Intrinsic::scmp: {
case llvm::Intrinsic::scmp:
case llvm::Intrinsic::clmul: {
PARSE_BINOP();
addNoundefAssumes(i, {a, b});
BinOp::Op op;
Expand All @@ -866,6 +867,7 @@ class llvm2alive_ : public llvm::InstVisitor<llvm2alive_, unique_ptr<Instr>> {
case llvm::Intrinsic::abs: op = BinOp::Abs; break;
case llvm::Intrinsic::ucmp: op = BinOp::UCmp; break;
case llvm::Intrinsic::scmp: op = BinOp::SCmp; break;
case llvm::Intrinsic::clmul: op = BinOp::Clmul; break;
default: UNREACHABLE();
}
ret = make_unique<BinOp>(*ty, value_name(i), *a, *b, op);
Expand Down
12 changes: 12 additions & 0 deletions smt/expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1124,6 +1124,18 @@ expr expr::ctpop() const {
return res;
}

expr expr::clmul(const expr &rhs) const {
C(rhs);
auto nbits = bits();

auto res = mkUInt(0, sort());
for (unsigned i = 0; i < nbits; ++i) {
res = res ^ (extract(i, i).sext(nbits - 1) & (rhs << mkUInt(i, sort())));
}

return res;
}

expr expr::umin(const expr &rhs) const {
return mkIf(ule(rhs), *this, rhs);
}
Expand Down
1 change: 1 addition & 0 deletions smt/expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ class expr {
expr cttz(const expr &val_zero) const;
expr ctlz() const;
expr ctpop() const;
expr clmul(const expr &rhs) const;

expr umin(const expr &rhs) const;
expr umax(const expr &rhs) const;
Expand Down
20 changes: 20 additions & 0 deletions tests/alive-tv/clmul.srctgt.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
; clmulr(x, y)
; = clmul(zext(x, 2 * BW), zext(y, 2 * BW)) >> (BW - 1)
; = bitreverse(clmul(bitreverse(x)))

define i8 @src(i8 %x, i8 %y) {
%extx = zext i8 %x to i16
%exty = zext i8 %y to i16
%clmul = call i16 @llvm.clmul.i16(i16 %extx, i16 %exty)
%clmulr = lshr i16 %clmul, 7
%trunc = trunc i16 %clmulr to i8
ret i8 %trunc
}

define i8 @tgt(i8 %x, i8 %y) {
%rx = call i8 @llvm.bitreverse.i8(i8 %x)
%ry = call i8 @llvm.bitreverse.i8(i8 %y)
%clmul = call i8 @llvm.clmul.i8(i8 %rx, i8 %ry)
%clmulr = call i8 @llvm.bitreverse.i8(i8 %clmul)
ret i8 %clmulr
}
39 changes: 39 additions & 0 deletions tests/unit/clmul.opt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
Name: clmul constant1
%r = clmul i4 1, i4 2
=>
%r = 2

Name: clmul constant2
%r = clmul i4 5, i4 6
=>
%r = 14

Name: clmul constant3
%r = clmul i4 -4, i4 2
=>
%r = -8

Name: clmul constant4
%r = clmul i4 -4, i4 -5
=>
%r = 4

Name: clmul constant5
%r = clmul i8 0, i8 255
=>
%r = 0

Name: clmul constant6
%r = clmul i8 15, i8 15
=>
%r = 85

Name: clmul constant7
%r = clmul i8 1, i8 2
=>
%r = 2

Name: clmul constant8
%r = clmul i16 -1, i16 -2
=>
%r = -21846
1 change: 1 addition & 0 deletions tools/alive_lexer.re
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ space+ {
"abs" { return ABS; }
"ucmp" { return UCMP; }
"scmp" { return SCMP; }
"clmul" { return CLMUL; }
"oeq" { return OEQ; }
"ogt" { return OGT; }
"oge" { return OGE; }
Expand Down
3 changes: 3 additions & 0 deletions tools/alive_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,7 @@ static unsigned parse_binop_flags(token op_token) {
case ABS:
case UCMP:
case SCMP:
case CLMUL:
return BinOp::None;
default:
UNREACHABLE();
Expand Down Expand Up @@ -782,6 +783,7 @@ static unique_ptr<Instr> parse_binop(string_view name, token op_token) {
case ABS: op = BinOp::Abs; break;
case UCMP: op = BinOp::UCmp; break;
case SCMP: op = BinOp::SCmp; break;
case CLMUL: op = BinOp::Clmul; break;
default:
UNREACHABLE();
}
Expand Down Expand Up @@ -1273,6 +1275,7 @@ static unique_ptr<Instr> parse_instr(string_view name) {
case ABS:
case UCMP:
case SCMP:
case CLMUL:
return parse_binop(name, t);
case FADD:
case FSUB:
Expand Down
1 change: 1 addition & 0 deletions tools/tokens.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ TOKEN(BITREVERSE)
TOKEN(BSWAP)
TOKEN(BOR)
TOKEN(CALL)
TOKEN(CLMUL)
TOKEN(COMMA)
TOKEN(CONSTANT)
TOKEN(CEQ)
Expand Down
Loading