Changeset 6295


Ignore:
Timestamp:
Jan 19, 2019, 2:44:58 PM (3 months ago)
Author:
cameron
Message:

Merge branch 'feat-simd-ternary' into 'master'

Implementing both simd_binary and simd_ternary operations

See merge request cameron/parabix-devel!1

Location:
icGREP/icgrep-devel/icgrep/IR_Gen
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/IR_Gen/idisa_avx_builder.cpp

    r6234 r6295  
    876876Value * IDISA_AVX512F_Builder::simd_if(unsigned fw, Value * cond, Value * a, Value * b) {
    877877    if (fw == 1) {
    878         Value * ternLogicFn = Intrinsic::getDeclaration(getModule(),  Intrinsic::x86_avx512_mask_pternlog_d_512);
    879878        // Form the 8-bit table for simd-if based on the bitwise values from cond, a and b.
    880879        //   (cond, a, b) =  (111), (110), (101), (100), (011), (010), (001), (000)
    881880        // if(cond, a, b) =    1      1      0      0      1      0      1      0    = 0xCA
    882         Constant * simd_if_mask = ConstantInt::get(getInt32Ty(), 0xCA);
    883         Constant * writemask = ConstantInt::getAllOnesValue(getInt16Ty());
    884         Value * args[5] = {fwCast(32, cond), fwCast(32, a), fwCast(32, b), simd_if_mask, writemask};
    885         Value * rslt = CreateCall(ternLogicFn, args);
    886         return rslt;
     881        return simd_ternary(0xCA, cond, a, b);
    887882    }
    888883    return IDISA_AVX2_Builder::simd_if(fw, cond, a, b);
     884}
     885
     886Value * IDISA_AVX512F_Builder::simd_ternary(unsigned char mask, Value * a, Value * b, Value * c) {
     887    Value * ternLogicFn = Intrinsic::getDeclaration(getModule(),  Intrinsic::x86_avx512_mask_pternlog_d_512);
     888    Constant * simd_mask = ConstantInt::get(getInt32Ty(), mask);
     889    Constant * writemask = ConstantInt::getAllOnesValue(getInt16Ty());
     890    Value * args[5] = {fwCast(32, a), fwCast(32, b), fwCast(32, c), simd_mask, writemask};
     891    Value * rslt = CreateCall(ternLogicFn, args);
     892    return rslt;
    889893}
    890894
  • icGREP/icgrep-devel/icgrep/IR_Gen/idisa_avx_builder.h

    r6234 r6295  
    9191    llvm::Value * mvmd_sll(unsigned fw, llvm::Value * a, llvm::Value * shift, const bool safe) override;
    9292    llvm::Value * simd_if(unsigned fw, llvm::Value * cond, llvm::Value * a, llvm::Value * b) override;
     93    llvm::Value * simd_ternary(unsigned char mask, llvm::Value * a, llvm::Value * b, llvm::Value * c) override;
    9394
    9495    ~IDISA_AVX512F_Builder() {
  • icGREP/icgrep-devel/icgrep/IR_Gen/idisa_builder.cpp

    r6220 r6295  
    522522    }
    523523}
     524
     525Value * IDISA_Builder::simd_binary(unsigned char mask, Value * a, Value * b) {
     526    // Form the 4-bit table for based on the bitwise values from a and b
     527    // a b | mask = 0b1000
     528    // 0 0 | 0
     529    // 0 1 | 0
     530    // 1 0 | 0
     531    // 1 1 | 1
     532    switch(mask) {
     533        case 0b00000000: return allZeroes();
     534        case 0b00000001: return CreateNot(CreateOr(a, b));
     535        case 0b00000010: return CreateAnd(CreateNot(a), b);
     536        case 0b00000011: return CreateNot(a);
     537        case 0b00000100: return CreateAnd(a, CreateNot(b));
     538        case 0b00000101: return CreateNot(b);
     539        case 0b00000110: return CreateXor(a, b);
     540        case 0b00000111: return CreateNot(CreateAnd(a, b));
     541        case 0b00001000: return CreateAnd(a, b);
     542        case 0b00001001: return CreateNot(CreateXor(a, b));
     543        case 0b00001010: return b;
     544        case 0b00001011: return CreateOr(CreateNot(a), b);
     545        case 0b00001100: return a;
     546        case 0b00001101: return CreateOr(a, CreateNot(b));
     547        case 0b00001110: return CreateOr(a, b);
     548        case 0b00001111: return allOnes();
     549        default: report_fatal_error("simd_binary mask is in wrong format!");
     550    }
     551}
     552
     553Value * IDISA_Builder::simd_ternary(unsigned char mask, Value * a, Value * b, Value * c) {
     554    if (mask == 0) return allZeroes();
     555    else if (mask == 0xFF) return allOnes();
     556
     557    unsigned char not_a_mask = mask & 0x0F;
     558    unsigned char a_mask = (mask >> 4) & 0x0F;
     559
     560    if (a_mask == not_a_mask) return simd_binary(a_mask, b, c);
     561    else if ((a_mask ^ not_a_mask) == 0x0F) return CreateXor(a, simd_binary(not_a_mask, b, c));
     562
     563    Value * bc_hi = simd_binary(a_mask, b, c);
     564    Value * bc_lo = simd_binary(not_a_mask, b, c);
     565    Value * a_bc = CreateAnd(a, bc_hi);
     566    Value * not_a_bc = CreateAnd(CreateNot(a), bc_lo);
     567    return CreateOr(a_bc, not_a_bc);
     568}
    524569   
    525570Value * IDISA_Builder::esimd_mergeh(unsigned fw, Value * a, Value * b) {
  • icGREP/icgrep-devel/icgrep/IR_Gen/idisa_builder.h

    r6220 r6295  
    127127    virtual llvm::Value * simd_umin(unsigned fw, llvm::Value * a, llvm::Value * b);
    128128    virtual llvm::Value * simd_if(unsigned fw, llvm::Value * cond, llvm::Value * a, llvm::Value * b);
     129    llvm::Value * simd_binary(unsigned char mask, llvm::Value * a, llvm::Value * b);
     130    virtual llvm::Value * simd_ternary(unsigned char mask, llvm::Value * a, llvm::Value * b, llvm::Value * c);
    129131   
    130132    virtual llvm::Value * simd_slli(unsigned fw, llvm::Value * a, unsigned shift);
Note: See TracChangeset for help on using the changeset viewer.