Skip to content

Commit 975b41f

Browse files
authored
Add support for pext/pdep (#1320)
1 parent 176eeff commit 975b41f

11 files changed

Lines changed: 108 additions & 2 deletions

File tree

ir/instr.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ void BinOp::print(ostream &os) const {
187187
case UCmp: str = "ucmp "; break;
188188
case SCmp: str = "scmp "; break;
189189
case Clmul: str = "clmul "; break;
190+
case PExt: str = "pext "; break;
191+
case PDep: str = "pdep "; break;
190192
}
191193

192194
os << getName() << " = " << str;
@@ -479,6 +481,16 @@ StateValue BinOp::toSMT(State &s) const {
479481
return {a.clmul(b), ap && bp};
480482
};
481483
break;
484+
case PExt:
485+
fn = [&](auto &a, auto &ap, auto &b, auto &bp) -> StateValue {
486+
return {a.pext(b), ap && bp};
487+
};
488+
break;
489+
case PDep:
490+
fn = [&](auto &a, auto &ap, auto &b, auto &bp) -> StateValue {
491+
return {a.pdep(b), ap && bp};
492+
};
493+
break;
482494
}
483495

484496
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, Clmul };
44+
UCmp, SCmp, Clmul, PExt, PDep };
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: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -841,7 +841,9 @@ class llvm2alive_ : public llvm::InstVisitor<llvm2alive_, unique_ptr<Instr>> {
841841
case llvm::Intrinsic::abs:
842842
case llvm::Intrinsic::ucmp:
843843
case llvm::Intrinsic::scmp:
844-
case llvm::Intrinsic::clmul: {
844+
case llvm::Intrinsic::clmul:
845+
case llvm::Intrinsic::pext:
846+
case llvm::Intrinsic::pdep: {
845847
PARSE_BINOP();
846848
addNoundefAssumes(i, {a, b});
847849
BinOp::Op op;
@@ -868,6 +870,8 @@ class llvm2alive_ : public llvm::InstVisitor<llvm2alive_, unique_ptr<Instr>> {
868870
case llvm::Intrinsic::ucmp: op = BinOp::UCmp; break;
869871
case llvm::Intrinsic::scmp: op = BinOp::SCmp; break;
870872
case llvm::Intrinsic::clmul: op = BinOp::Clmul; break;
873+
case llvm::Intrinsic::pext: op = BinOp::PExt; break;
874+
case llvm::Intrinsic::pdep: op = BinOp::PDep; break;
871875
default: UNREACHABLE();
872876
}
873877
ret = make_unique<BinOp>(*ty, value_name(i), *a, *b, op);

smt/expr.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,6 +1136,36 @@ expr expr::clmul(const expr &rhs) const {
11361136
return res;
11371137
}
11381138

1139+
expr expr::pext(const expr &mask) const {
1140+
C(mask);
1141+
auto nbits = bits();
1142+
1143+
auto res = mkUInt(0, sort());
1144+
auto shamt = mkUInt(0, sort());
1145+
for (unsigned i = 0; i < nbits; ++i) {
1146+
auto active = mask.extract(i, i).zext(nbits - 1);
1147+
res = res | ((active & extract(i, i).zext(nbits - 1)) << shamt);
1148+
shamt = shamt + active;
1149+
}
1150+
1151+
return res;
1152+
}
1153+
1154+
expr expr::pdep(const expr &mask) const {
1155+
C(mask);
1156+
auto nbits = bits();
1157+
1158+
auto res = mkUInt(0, sort());
1159+
auto shamt = mkUInt(0, sort());
1160+
for (unsigned i = 0; i < nbits; ++i) {
1161+
auto active = mask.extract(i, i).zext(nbits - 1);
1162+
res = res | ((active & lshr(shamt)) << mkUInt(i, sort()));
1163+
shamt = shamt + active;
1164+
}
1165+
1166+
return res;
1167+
}
1168+
11391169
expr expr::umin(const expr &rhs) const {
11401170
return mkIf(ule(rhs), *this, rhs);
11411171
}

smt/expr.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,8 @@ class expr {
218218
expr ctlz() const;
219219
expr ctpop() const;
220220
expr clmul(const expr &rhs) const;
221+
expr pext(const expr &mask) const;
222+
expr pdep(const expr &mask) const;
221223

222224
expr umin(const expr &rhs) const;
223225
expr umax(const expr &rhs) const;

tests/alive-tv/pext-pdep.srctgt.ll

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
define i8 @src(i8 %val, i8 %mask) {
2+
%pext = call i8 @llvm.pext.i8(i8 %val, i8 %mask)
3+
%pdep = call i8 @llvm.pdep.i8(i8 %pext, i8 %mask)
4+
ret i8 %pdep
5+
}
6+
7+
define i8 @tgt(i8 %val, i8 %mask) {
8+
%masked = and i8 %val, %mask
9+
ret i8 %masked
10+
}

tests/unit/pdep.opt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Name: pdep constant1
2+
%r = pdep i8 10, i8 204
3+
=>
4+
%r = 136
5+
6+
Name: pdep constant2
7+
%r = pdep i8 15, i8 170
8+
=>
9+
%r = 170
10+
11+
Name: pdep simplify1
12+
%r = pdep i8 %x, i8 0
13+
=>
14+
%r = 0
15+
16+
Name: pdep simplify2
17+
%r = pdep i8 %x, i8 255
18+
=>
19+
%r = %x

tests/unit/pext.opt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Name: pext constant1
2+
%r = pext i8 170, i8 204
3+
=>
4+
%r = 10
5+
6+
Name: pext constant2
7+
%r = pext i8 255, i8 170
8+
=>
9+
%r = 15
10+
11+
Name: pext simplify1
12+
%r = pext i8 %x, i8 0
13+
=>
14+
%r = 0
15+
16+
Name: pext simplify2
17+
%r = pext i8 %x, i8 255
18+
=>
19+
%r = %x

tools/alive_lexer.re

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,8 @@ space+ {
287287
"ucmp" { return UCMP; }
288288
"scmp" { return SCMP; }
289289
"clmul" { return CLMUL; }
290+
"pext" { return PEXT; }
291+
"pdep" { return PDEP; }
290292
"oeq" { return OEQ; }
291293
"ogt" { return OGT; }
292294
"oge" { return OGE; }

tools/alive_parser.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,8 @@ static unsigned parse_binop_flags(token op_token) {
711711
case UCMP:
712712
case SCMP:
713713
case CLMUL:
714+
case PEXT:
715+
case PDEP:
714716
return BinOp::None;
715717
default:
716718
UNREACHABLE();
@@ -784,6 +786,8 @@ static unique_ptr<Instr> parse_binop(string_view name, token op_token) {
784786
case UCMP: op = BinOp::UCmp; break;
785787
case SCMP: op = BinOp::SCmp; break;
786788
case CLMUL: op = BinOp::Clmul; break;
789+
case PEXT: op = BinOp::PExt; break;
790+
case PDEP: op = BinOp::PDep; break;
787791
default:
788792
UNREACHABLE();
789793
}
@@ -1276,6 +1280,8 @@ static unique_ptr<Instr> parse_instr(string_view name) {
12761280
case UCMP:
12771281
case SCMP:
12781282
case CLMUL:
1283+
case PEXT:
1284+
case PDEP:
12791285
return parse_binop(name, t);
12801286
case FADD:
12811287
case FSUB:

0 commit comments

Comments
 (0)