Skip to content

Commit d1fe790

Browse files
authored
Add support for clmul (#1318)
1 parent cb9fbd5 commit d1fe790

10 files changed

Lines changed: 87 additions & 2 deletions

File tree

ir/instr.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ void BinOp::print(ostream &os) const {
186186
case Abs: str = "abs "; break;
187187
case UCmp: str = "ucmp "; break;
188188
case SCmp: str = "scmp "; break;
189+
case Clmul: str = "clmul "; break;
189190
}
190191

191192
os << getName() << " = " << str;
@@ -473,6 +474,11 @@ StateValue BinOp::toSMT(State &s) const {
473474
ap && bp};
474475
};
475476
break;
477+
case Clmul:
478+
fn = [&](auto &a, auto &ap, auto &b, auto &bp) -> StateValue {
479+
return {a.clmul(b), ap && bp};
480+
};
481+
break;
476482
}
477483

478484
function<pair<StateValue,StateValue>(const expr&, const expr&, const expr&,

ir/instr.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class BinOp final : public Instr {
4141
SAdd_Overflow, UAdd_Overflow, SSub_Overflow, USub_Overflow,
4242
SMul_Overflow, UMul_Overflow,
4343
And, Or, Xor, Cttz, Ctlz, UMin, UMax, SMin, SMax, Abs,
44-
UCmp, SCmp };
44+
UCmp, SCmp, Clmul };
4545
enum Flags { None = 0, NSW = 1 << 0, NUW = 1 << 1, Exact = 1 << 2, Disjoint = 1 << 3 };
4646

4747
private:

llvm_util/llvm2alive.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -840,7 +840,8 @@ class llvm2alive_ : public llvm::InstVisitor<llvm2alive_, unique_ptr<Instr>> {
840840
case llvm::Intrinsic::smax:
841841
case llvm::Intrinsic::abs:
842842
case llvm::Intrinsic::ucmp:
843-
case llvm::Intrinsic::scmp: {
843+
case llvm::Intrinsic::scmp:
844+
case llvm::Intrinsic::clmul: {
844845
PARSE_BINOP();
845846
addNoundefAssumes(i, {a, b});
846847
BinOp::Op op;
@@ -866,6 +867,7 @@ class llvm2alive_ : public llvm::InstVisitor<llvm2alive_, unique_ptr<Instr>> {
866867
case llvm::Intrinsic::abs: op = BinOp::Abs; break;
867868
case llvm::Intrinsic::ucmp: op = BinOp::UCmp; break;
868869
case llvm::Intrinsic::scmp: op = BinOp::SCmp; break;
870+
case llvm::Intrinsic::clmul: op = BinOp::Clmul; break;
869871
default: UNREACHABLE();
870872
}
871873
ret = make_unique<BinOp>(*ty, value_name(i), *a, *b, op);

smt/expr.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1124,6 +1124,18 @@ expr expr::ctpop() const {
11241124
return res;
11251125
}
11261126

1127+
expr expr::clmul(const expr &rhs) const {
1128+
C(rhs);
1129+
auto nbits = bits();
1130+
1131+
auto res = mkUInt(0, sort());
1132+
for (unsigned i = 0; i < nbits; ++i) {
1133+
res = res ^ (extract(i, i).sext(nbits - 1) & (rhs << mkUInt(i, sort())));
1134+
}
1135+
1136+
return res;
1137+
}
1138+
11271139
expr expr::umin(const expr &rhs) const {
11281140
return mkIf(ule(rhs), *this, rhs);
11291141
}

smt/expr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ class expr {
217217
expr cttz(const expr &val_zero) const;
218218
expr ctlz() const;
219219
expr ctpop() const;
220+
expr clmul(const expr &rhs) const;
220221

221222
expr umin(const expr &rhs) const;
222223
expr umax(const expr &rhs) const;

tests/alive-tv/clmul.srctgt.ll

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
; clmulr(x, y)
2+
; = clmul(zext(x, 2 * BW), zext(y, 2 * BW)) >> (BW - 1)
3+
; = bitreverse(clmul(bitreverse(x)))
4+
5+
define i8 @src(i8 %x, i8 %y) {
6+
%extx = zext i8 %x to i16
7+
%exty = zext i8 %y to i16
8+
%clmul = call i16 @llvm.clmul.i16(i16 %extx, i16 %exty)
9+
%clmulr = lshr i16 %clmul, 7
10+
%trunc = trunc i16 %clmulr to i8
11+
ret i8 %trunc
12+
}
13+
14+
define i8 @tgt(i8 %x, i8 %y) {
15+
%rx = call i8 @llvm.bitreverse.i8(i8 %x)
16+
%ry = call i8 @llvm.bitreverse.i8(i8 %y)
17+
%clmul = call i8 @llvm.clmul.i8(i8 %rx, i8 %ry)
18+
%clmulr = call i8 @llvm.bitreverse.i8(i8 %clmul)
19+
ret i8 %clmulr
20+
}

tests/unit/clmul.opt

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
Name: clmul constant1
2+
%r = clmul i4 1, i4 2
3+
=>
4+
%r = 2
5+
6+
Name: clmul constant2
7+
%r = clmul i4 5, i4 6
8+
=>
9+
%r = 14
10+
11+
Name: clmul constant3
12+
%r = clmul i4 -4, i4 2
13+
=>
14+
%r = -8
15+
16+
Name: clmul constant4
17+
%r = clmul i4 -4, i4 -5
18+
=>
19+
%r = 4
20+
21+
Name: clmul constant5
22+
%r = clmul i8 0, i8 255
23+
=>
24+
%r = 0
25+
26+
Name: clmul constant6
27+
%r = clmul i8 15, i8 15
28+
=>
29+
%r = 85
30+
31+
Name: clmul constant7
32+
%r = clmul i8 1, i8 2
33+
=>
34+
%r = 2
35+
36+
Name: clmul constant8
37+
%r = clmul i16 -1, i16 -2
38+
=>
39+
%r = -21846

tools/alive_lexer.re

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ space+ {
286286
"abs" { return ABS; }
287287
"ucmp" { return UCMP; }
288288
"scmp" { return SCMP; }
289+
"clmul" { return CLMUL; }
289290
"oeq" { return OEQ; }
290291
"ogt" { return OGT; }
291292
"oge" { return OGE; }

tools/alive_parser.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,7 @@ static unsigned parse_binop_flags(token op_token) {
710710
case ABS:
711711
case UCMP:
712712
case SCMP:
713+
case CLMUL:
713714
return BinOp::None;
714715
default:
715716
UNREACHABLE();
@@ -782,6 +783,7 @@ static unique_ptr<Instr> parse_binop(string_view name, token op_token) {
782783
case ABS: op = BinOp::Abs; break;
783784
case UCMP: op = BinOp::UCmp; break;
784785
case SCMP: op = BinOp::SCmp; break;
786+
case CLMUL: op = BinOp::Clmul; break;
785787
default:
786788
UNREACHABLE();
787789
}
@@ -1273,6 +1275,7 @@ static unique_ptr<Instr> parse_instr(string_view name) {
12731275
case ABS:
12741276
case UCMP:
12751277
case SCMP:
1278+
case CLMUL:
12761279
return parse_binop(name, t);
12771280
case FADD:
12781281
case FSUB:

tools/tokens.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ TOKEN(BITREVERSE)
1515
TOKEN(BSWAP)
1616
TOKEN(BOR)
1717
TOKEN(CALL)
18+
TOKEN(CLMUL)
1819
TOKEN(COMMA)
1920
TOKEN(CONSTANT)
2021
TOKEN(CEQ)

0 commit comments

Comments
 (0)