18
18
#include " WebAssemblySubtarget.h"
19
19
#include " WebAssemblyTargetMachine.h"
20
20
#include " WebAssemblyUtilities.h"
21
+ #include " llvm/ADT/SmallVector.h"
21
22
#include " llvm/CodeGen/CallingConvLower.h"
23
+ #include " llvm/CodeGen/ISDOpcodes.h"
22
24
#include " llvm/CodeGen/MachineFrameInfo.h"
23
25
#include " llvm/CodeGen/MachineInstrBuilder.h"
24
26
#include " llvm/CodeGen/MachineJumpTableInfo.h"
25
27
#include " llvm/CodeGen/MachineModuleInfo.h"
26
28
#include " llvm/CodeGen/MachineRegisterInfo.h"
29
+ #include " llvm/CodeGen/SDPatternMatch.h"
27
30
#include " llvm/CodeGen/SelectionDAG.h"
28
31
#include " llvm/CodeGen/SelectionDAGNodes.h"
29
32
#include " llvm/IR/DiagnosticInfo.h"
35
38
#include " llvm/Support/ErrorHandling.h"
36
39
#include " llvm/Support/KnownBits.h"
37
40
#include " llvm/Support/MathExtras.h"
41
+ #include " llvm/Support/raw_ostream.h"
38
42
#include " llvm/Target/TargetOptions.h"
43
+ #include < iostream>
39
44
using namespace llvm ;
45
+ using namespace llvm ::SDPatternMatch;
40
46
41
47
#define DEBUG_TYPE " wasm-lower"
42
48
@@ -3287,6 +3293,63 @@ static SDValue performSETCCCombine(SDNode *N,
3287
3293
3288
3294
return SDValue ();
3289
3295
}
3296
+ static SmallVector<int > buildPowerIndexArray (int Power, int NumElements) {
3297
+ int From = pow (Power, 2 );
3298
+ int To = pow (Power + 1 , 2 );
3299
+
3300
+ SmallVector<int > Res;
3301
+ for (int I = From; I < To; I++)
3302
+ Res.push_back (I);
3303
+
3304
+ for (int I = To; I < NumElements; I++)
3305
+ Res.push_back (-1 );
3306
+
3307
+ llvm::errs () << " Created res: " ;
3308
+ for (auto N : Res)
3309
+ llvm::errs () << N << " " ;
3310
+ llvm::errs () << " \n " ;
3311
+ return Res;
3312
+ }
3313
+ static bool isAndShuffle (SDNode *N, SDValue Result, int Power) {
3314
+ // base case when power = n/2
3315
+ EVT VT = N->getOperand (0 )->getValueType (0 );
3316
+ int NumElements = VT.getVectorNumElements ();
3317
+ bool IsBaseCase = NumElements / 2 == Power;
3318
+
3319
+ // build power indices
3320
+ SmallVector<int > PowerIndices = buildPowerIndexArray (Power, NumElements);
3321
+ // Base case: A shuffle for a setcc (v), (ne, 0) for half elements
3322
+ if (IsBaseCase)
3323
+ return sd_match (N, m_Shuffle (m_SetCC (m_Value (Result), m_Zero (),
3324
+ m_SpecificCondCode (ISD::SETNE)),
3325
+ m_Opc (ISD::POISON),
3326
+ m_SpecificMask (PowerIndices)));
3327
+
3328
+ // Recursive case: Check if it is an AND.
3329
+ if (N->getOpcode () != ISD::AND)
3330
+ return false ;
3331
+
3332
+ SDValue Matched;
3333
+ if (sd_match (N, m_And (m_Value (Result),
3334
+ m_Shuffle (m_SetCC (m_Value (Matched), m_Zero (),
3335
+ m_SpecificCondCode (ISD::SETNE)),
3336
+ m_Opc (ISD::POISON),
3337
+ m_SpecificMask (PowerIndices))))) {
3338
+ return isAndShuffle (Matched.getNode (), Result, Power * 2 );
3339
+ }
3340
+ return false ;
3341
+ }
3342
+ static SDValue performANDCombine (SDNode *N, SelectionDAG &DAG) {
3343
+ // FIX: Not sure why but Dagcombine doesn't see an AND opcode to hook to the
3344
+ // function even though initial selection dag entry has AND nodes
3345
+ assert (N->getOpcode () == ISD::AND);
3346
+ SDLoc DL (N);
3347
+ SDValue Matched;
3348
+
3349
+ if (isAndShuffle (N, Matched, 0 ))
3350
+ return Matched;
3351
+ return SDValue ();
3352
+ }
3290
3353
3291
3354
static SDValue performMulCombine (SDNode *N, SelectionDAG &DAG) {
3292
3355
assert (N->getOpcode () == ISD::MUL);
@@ -3378,6 +3441,8 @@ static SDValue performMulCombine(SDNode *N, SelectionDAG &DAG) {
3378
3441
SDValue
3379
3442
WebAssemblyTargetLowering::PerformDAGCombine (SDNode *N,
3380
3443
DAGCombinerInfo &DCI) const {
3444
+ // N->print(llvm::errs());
3445
+ // std::cout << "\n";
3381
3446
switch (N->getOpcode ()) {
3382
3447
default :
3383
3448
return SDValue ();
@@ -3402,6 +3467,8 @@ WebAssemblyTargetLowering::PerformDAGCombine(SDNode *N,
3402
3467
return performTruncateCombine (N, DCI);
3403
3468
case ISD::INTRINSIC_WO_CHAIN:
3404
3469
return performLowerPartialReduction (N, DCI.DAG );
3470
+ case ISD::AND:
3471
+ return performANDCombine (N, DCI.DAG );
3405
3472
case ISD::MUL:
3406
3473
return performMulCombine (N, DCI.DAG );
3407
3474
}
0 commit comments