Skip to content

Commit 50ca839

Browse files
committed
[WebAssembly] Constant fold dot operation
1 parent 5563f46 commit 50ca839

File tree

2 files changed

+39
-6
lines changed

2 files changed

+39
-6
lines changed

llvm/lib/Analysis/ConstantFolding.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1657,6 +1657,7 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) {
16571657
case Intrinsic::aarch64_sve_convert_from_svbool:
16581658
case Intrinsic::wasm_alltrue:
16591659
case Intrinsic::wasm_anytrue:
1660+
case Intrinsic::wasm_dot:
16601661
// WebAssembly float semantics are always known
16611662
case Intrinsic::wasm_trunc_signed:
16621663
case Intrinsic::wasm_trunc_unsigned:
@@ -3826,6 +3827,36 @@ static Constant *ConstantFoldFixedVectorCall(
38263827
}
38273828
return ConstantVector::get(Result);
38283829
}
3830+
case Intrinsic::wasm_dot: {
3831+
unsigned NumElements =
3832+
cast<FixedVectorType>(Operands[0]->getType())->getNumElements();
3833+
3834+
assert(NumElements == 8 && NumElements / 2 == Result.size() &&
3835+
"wasm dot takes i16x8 and produce i32x4");
3836+
assert(Ty->isIntegerTy());
3837+
SmallVector<APInt, 8> MulVector;
3838+
3839+
for (unsigned I = 0; I < NumElements; ++I) {
3840+
ConstantInt *Elt0 =
3841+
cast<ConstantInt>(Operands[0]->getAggregateElement(I));
3842+
ConstantInt *Elt1 =
3843+
cast<ConstantInt>(Operands[1]->getAggregateElement(I));
3844+
3845+
// sext 32 first, according to specs
3846+
APInt IMul = Elt0->getValue().sext(32) * Elt1->getValue().sext(32);
3847+
3848+
// TODO: imul in specs includes a modulo operation
3849+
// Is this performed automatically via trunc = true in APInt creation of *
3850+
MulVector.push_back(IMul);
3851+
}
3852+
for (unsigned I = 0; I < Result.size(); ++I) {
3853+
// Same case as with imul
3854+
APInt IAdd = MulVector[I] + MulVector[I + Result.size()];
3855+
Result[I] = ConstantInt::get(Ty, IAdd);
3856+
}
3857+
3858+
return ConstantVector::get(Result);
3859+
}
38293860
default:
38303861
break;
38313862
}

llvm/test/Transforms/InstSimplify/ConstProp/WebAssembly/dot.ll

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,28 @@ target triple = "wasm32-unknown-unknown"
99

1010
define <4 x i32> @dot_zero() {
1111
; CHECK-LABEL: define <4 x i32> @dot_zero() {
12-
; CHECK-NEXT: [[RES:%.*]] = tail call <4 x i32> @llvm.wasm.dot(<8 x i16> zeroinitializer, <8 x i16> zeroinitializer)
13-
; CHECK-NEXT: ret <4 x i32> [[RES]]
12+
; CHECK-NEXT: ret <4 x i32> zeroinitializer
1413
;
1514
%res = tail call <4 x i32> @llvm.wasm.dot(<8 x i16> zeroinitializer, <8 x i16> zeroinitializer)
1615
ret <4 x i32> %res
1716
}
1817

18+
; a = 1 2 3 4 5 6 7 8
19+
; b = 1 2 3 4 5 6 7 8
20+
; k1|k2 = a * b = 1 4 9 16 25 36 49 64
21+
; k1 + k2 = (1+25) | (4+36) | (9+49) | (16+64)
22+
; result = 26 | 40 | 58 | 80
1923
define <4 x i32> @dot_nonzero() {
2024
; CHECK-LABEL: define <4 x i32> @dot_nonzero() {
21-
; CHECK-NEXT: [[RES:%.*]] = tail call <4 x i32> @llvm.wasm.dot(<8 x i16> <i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7, i16 8>, <8 x i16> <i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7, i16 8>)
22-
; CHECK-NEXT: ret <4 x i32> [[RES]]
25+
; CHECK-NEXT: ret <4 x i32> <i32 26, i32 40, i32 58, i32 80>
2326
;
2427
%res = tail call <4 x i32> @llvm.wasm.dot(<8 x i16> <i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7, i16 8>, <8 x i16> <i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7, i16 8>)
2528
ret <4 x i32> %res
2629
}
2730

2831
define <4 x i32> @dot_doubly_negative() {
2932
; CHECK-LABEL: define <4 x i32> @dot_doubly_negative() {
30-
; CHECK-NEXT: [[RES:%.*]] = tail call <4 x i32> @llvm.wasm.dot(<8 x i16> splat (i16 -1), <8 x i16> splat (i16 -1))
31-
; CHECK-NEXT: ret <4 x i32> [[RES]]
33+
; CHECK-NEXT: ret <4 x i32> splat (i32 2)
3234
;
3335
%res = tail call <4 x i32> @llvm.wasm.dot(<8 x i16> <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>, <8 x i16> <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>)
3436
ret <4 x i32> %res

0 commit comments

Comments
 (0)