Skip to content

Commit 07ed82b

Browse files
committed
[WebAssembly] Rearrange new TTI hook code
1 parent 41edf7d commit 07ed82b

File tree

5 files changed

+89
-111
lines changed

5 files changed

+89
-111
lines changed

llvm/lib/Target/WebAssembly/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ add_llvm_target(WebAssemblyCodeGen
3232
WebAssemblyFixIrreducibleControlFlow.cpp
3333
WebAssemblyFixFunctionBitcasts.cpp
3434
WebAssemblyFrameLowering.cpp
35-
WebAssemblyInstCombineIntrinsic.cpp
3635
WebAssemblyISelDAGToDAG.cpp
3736
WebAssemblyISelLowering.cpp
3837
WebAssemblyInstrInfo.cpp

llvm/lib/Target/WebAssembly/WebAssemblyInstCombineIntrinsic.cpp

Lines changed: 0 additions & 107 deletions
This file was deleted.

llvm/lib/Target/WebAssembly/WebAssemblyTargetTransformInfo.cpp

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
//===----------------------------------------------------------------------===//
1414

1515
#include "WebAssemblyTargetTransformInfo.h"
16+
#include "llvm/IR/IntrinsicInst.h"
17+
#include "llvm/IR/IntrinsicsWebAssembly.h"
18+
#include "llvm/Transforms/InstCombine/InstCombiner.h"
1619

1720
#include "llvm/CodeGen/CostTable.h"
1821
using namespace llvm;
@@ -493,3 +496,86 @@ bool WebAssemblyTTIImpl::isProfitableToSinkOperands(
493496

494497
return false;
495498
}
499+
500+
/// Attempt to convert [relaxed_]swizzle to shufflevector if the mask is
501+
/// constant.
502+
static Value *simplifyWasmSwizzle(const IntrinsicInst &II,
503+
InstCombiner::BuilderTy &Builder,
504+
bool IsRelaxed) {
505+
auto *V = dyn_cast<Constant>(II.getArgOperand(1));
506+
if (!V)
507+
return nullptr;
508+
509+
auto *VecTy = cast<FixedVectorType>(II.getType());
510+
unsigned NumElts = VecTy->getNumElements();
511+
assert(NumElts == 16);
512+
513+
// Construct a shuffle mask from constant integers or UNDEFs.
514+
int Indexes[16];
515+
bool AnyOutOfBounds = false;
516+
517+
for (unsigned I = 0; I < NumElts; ++I) {
518+
Constant *COp = V->getAggregateElement(I);
519+
if (!COp || (!isa<UndefValue>(COp) && !isa<ConstantInt>(COp)))
520+
return nullptr;
521+
522+
if (isa<UndefValue>(COp)) {
523+
Indexes[I] = -1;
524+
continue;
525+
}
526+
527+
int64_t Index = cast<ConstantInt>(COp)->getSExtValue();
528+
529+
if (Index >= NumElts && IsRelaxed) {
530+
// For lane indices above 15, the relaxed_swizzle operation can choose
531+
// between returning 0 or the lane at `Index % 16`. However, the choice
532+
// must be made consistently. As the WebAssembly spec states:
533+
//
534+
// "The result of relaxed operators are implementation-dependent, because
535+
// the set of possible results may depend on properties of the host
536+
// environment, such as its hardware. Technically, their behaviour is
537+
// controlled by a set of global parameters to the semantics that an
538+
// implementation can instantiate in different ways. These choices are
539+
// fixed, that is, parameters are constant during the execution of any
540+
// given program."
541+
//
542+
// The WebAssembly runtime may choose differently from us, so we can't
543+
// optimize a relaxed swizzle with lane indices above 15.
544+
return nullptr;
545+
}
546+
547+
if (Index >= NumElts || Index < 0) {
548+
AnyOutOfBounds = true;
549+
// If there are out-of-bounds indices, the swizzle instruction returns
550+
// zeroes in those lanes. We'll provide an all-zeroes vector as the
551+
// second argument to shufflevector and read the first element from it.
552+
Indexes[I] = NumElts;
553+
continue;
554+
}
555+
556+
Indexes[I] = Index;
557+
}
558+
559+
auto *V1 = II.getArgOperand(0);
560+
auto *V2 =
561+
AnyOutOfBounds ? Constant::getNullValue(VecTy) : PoisonValue::get(VecTy);
562+
563+
return Builder.CreateShuffleVector(V1, V2, ArrayRef(Indexes, NumElts));
564+
}
565+
566+
std::optional<Instruction *>
567+
WebAssemblyTTIImpl::instCombineIntrinsic(InstCombiner &IC,
568+
IntrinsicInst &II) const {
569+
Intrinsic::ID IID = II.getIntrinsicID();
570+
switch (IID) {
571+
case Intrinsic::wasm_swizzle:
572+
case Intrinsic::wasm_relaxed_swizzle:
573+
if (Value *V = simplifyWasmSwizzle(
574+
II, IC.Builder, IID == Intrinsic::wasm_relaxed_swizzle)) {
575+
return IC.replaceInstUsesWith(II, V);
576+
}
577+
break;
578+
}
579+
580+
return std::nullopt;
581+
}

llvm/lib/Target/WebAssembly/WebAssemblyTargetTransformInfo.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,6 @@ class WebAssemblyTTIImpl final : public BasicTTIImplBase<WebAssemblyTTIImpl> {
9090
TTI::TargetCostKind CostKind,
9191
unsigned Index, const Value *Op0,
9292
const Value *Op1) const override;
93-
std::optional<Instruction *>
94-
instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const override;
9593
InstructionCost getPartialReductionCost(
9694
unsigned Opcode, Type *InputTypeA, Type *InputTypeB, Type *AccumType,
9795
ElementCount VF, TTI::PartialReductionExtendKind OpAExtend,
@@ -105,6 +103,9 @@ class WebAssemblyTTIImpl final : public BasicTTIImplBase<WebAssemblyTTIImpl> {
105103
bool isProfitableToSinkOperands(Instruction *I,
106104
SmallVectorImpl<Use *> &Ops) const override;
107105

106+
std::optional<Instruction *>
107+
instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const override;
108+
108109
/// @}
109110
};
110111

llvm/utils/gn/secondary/llvm/lib/Target/WebAssembly/BUILD.gn

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ static_library("LLVMWebAssemblyCodeGen") {
5454
"WebAssemblyFixFunctionBitcasts.cpp",
5555
"WebAssemblyFixIrreducibleControlFlow.cpp",
5656
"WebAssemblyFrameLowering.cpp",
57-
"WebAssemblyInstCombineIntrinsic.cpp",
5857
"WebAssemblyISelDAGToDAG.cpp",
5958
"WebAssemblyISelLowering.cpp",
6059
"WebAssemblyInstrInfo.cpp",

0 commit comments

Comments
 (0)