@@ -426,10 +426,17 @@ bool isAllowedIRIntrinsic(Intrinsic::ID ID) {
426426 case Intrinsic::amdgcn_msad_u8:
427427 case Intrinsic::amdgcn_sad_hi_u8:
428428 case Intrinsic::amdgcn_sad_u16:
429+ case Intrinsic::amdgcn_qsad_pk_u16_u8:
430+ case Intrinsic::amdgcn_mqsad_pk_u16_u8:
431+ case Intrinsic::amdgcn_mqsad_u32_u8:
429432 case Intrinsic::amdgcn_mul_i24:
430433 case Intrinsic::amdgcn_mul_u24:
431434 case Intrinsic::amdgcn_mulhi_i24:
432435 case Intrinsic::amdgcn_mulhi_u24:
436+ case Intrinsic::amdgcn_alignbyte:
437+ case Intrinsic::amdgcn_sffbh:
438+ case Intrinsic::amdgcn_mbcnt_lo:
439+ case Intrinsic::amdgcn_mbcnt_hi:
433440 case Intrinsic::amdgcn_perm:
434441 case Intrinsic::amdgcn_bitop3:
435442 case Intrinsic::amdgcn_sdot2:
@@ -2543,17 +2550,60 @@ Value *packI32ToV2I16(IRBuilder<NoFolder> &B, Value *V, const Twine &Name) {
25432550 Twine (Name) + " .ins1" );
25442551}
25452552
2553+ Value *packI32PairToI64 (IRBuilder<NoFolder> &B, Value *Lo, Value *Hi,
2554+ const Twine &Name) {
2555+ LLVMContext &Ctx = Lo->getContext ();
2556+ Type *I64 = Type::getInt64Ty (Ctx);
2557+ Value *Lo64 = B.CreateZExt (Lo, I64 , Twine (Name) + " .lo64" );
2558+ Value *Hi64 = B.CreateZExt (Hi, I64 , Twine (Name) + " .hi64" );
2559+ Hi64 = B.CreateShl (Hi64, ConstantInt::get (I64 , 32 ),
2560+ Twine (Name) + " .hi.shift" );
2561+ return B.CreateOr (Lo64, Hi64, Twine (Name) + " .pack" );
2562+ }
2563+
2564+ Value *foldI64ToI32 (IRBuilder<NoFolder> &B, Value *V, const Twine &Name) {
2565+ LLVMContext &Ctx = V->getContext ();
2566+ Type *I32 = Type::getInt32Ty (Ctx);
2567+ Type *I64 = Type::getInt64Ty (Ctx);
2568+ Value *Lo = B.CreateTrunc (V, I32 , Twine (Name) + " .lo" );
2569+ Value *Hi = B.CreateLShr (V, ConstantInt::get (I64 , 32 ),
2570+ Twine (Name) + " .hi64" );
2571+ Hi = B.CreateTrunc (Hi, I32 , Twine (Name) + " .hi" );
2572+ return B.CreateXor (Lo, Hi, Twine (Name) + " .xor" );
2573+ }
2574+
2575+ Value *reduceV4I32ToI32 (IRBuilder<NoFolder> &B, Value *V,
2576+ std::minstd_rand &Gen, const Twine &Name) {
2577+ LLVMContext &Ctx = V->getContext ();
2578+ Value *A = B.CreateExtractElement (V, ci32 (Ctx, Gen () & 3u ),
2579+ Twine (Name) + " .a" );
2580+ Value *Bv = B.CreateExtractElement (V, ci32 (Ctx, Gen () & 3u ),
2581+ Twine (Name) + " .b" );
2582+ switch (Gen () % 4 ) {
2583+ case 0 :
2584+ return B.CreateXor (A, Bv, Twine (Name) + " .xor" );
2585+ case 1 :
2586+ return B.CreateAdd (A, Bv, Twine (Name) + " .add" );
2587+ case 2 :
2588+ return B.CreateOr (A, Bv, Twine (Name) + " .or" );
2589+ default :
2590+ return B.CreateSub (A, Bv, Twine (Name) + " .sub" );
2591+ }
2592+ }
2593+
25462594Value *emitRandomAMDGPUIntrinsicInstruction (IRBuilder<NoFolder> &B, Module &M,
25472595 Value *A, Value *Bv,
25482596 std::minstd_rand &Gen,
25492597 StringRef NamePrefix) {
25502598 LLVMContext &Ctx = M.getContext ();
25512599 Type *I32 = Type::getInt32Ty (Ctx);
2600+ Type *I64 = Type::getInt64Ty (Ctx);
25522601 Type *I1 = Type::getInt1Ty (Ctx);
2602+ auto *V4I32 = FixedVectorType::get (I32 , 4 );
25532603 Value *C = interestingI32 (Ctx, Gen);
25542604 Value *Clamp = ConstantInt::getFalse (Ctx);
25552605 bool AllowSUDot = envFlag (" FUZZX_ALLOW_C001_SUDOT_ISEL_ICE" , false );
2556- switch (Gen () % (AllowSUDot ? 21 : 19 )) {
2606+ switch (Gen () % (AllowSUDot ? 30 : 28 )) {
25572607 case 0 : {
25582608 unsigned Offset = Gen () % 32 ;
25592609 unsigned Width = Gen () % (33 - Offset);
@@ -2591,51 +2641,113 @@ Value *emitRandomAMDGPUIntrinsicInstruction(IRBuilder<NoFolder> &B, Module &M,
25912641 Intrinsic::getOrInsertDeclaration (&M, Intrinsic::amdgcn_sad_u16),
25922642 {A, Bv, C}, Twine (NamePrefix) + " .sad.u16" );
25932643 case 7 :
2644+ return foldI64ToI32 (
2645+ B,
2646+ B.CreateCall (Intrinsic::getOrInsertDeclaration (
2647+ &M, Intrinsic::amdgcn_qsad_pk_u16_u8),
2648+ {packI32PairToI64 (B, A, Bv,
2649+ Twine (NamePrefix) + " .qsad.a" ),
2650+ C,
2651+ packI32PairToI64 (B, Bv, A,
2652+ Twine (NamePrefix) + " .qsad.c" )},
2653+ Twine (NamePrefix) + " .qsad" ),
2654+ Twine (NamePrefix) + " .qsad.fold" );
2655+ case 8 :
2656+ return foldI64ToI32 (
2657+ B,
2658+ B.CreateCall (Intrinsic::getOrInsertDeclaration (
2659+ &M, Intrinsic::amdgcn_mqsad_pk_u16_u8),
2660+ {packI32PairToI64 (B, A, C,
2661+ Twine (NamePrefix) + " .mqsad.pk.a" ),
2662+ Bv,
2663+ packI32PairToI64 (B, C, A,
2664+ Twine (NamePrefix) + " .mqsad.pk.c" )},
2665+ Twine (NamePrefix) + " .mqsad.pk" ),
2666+ Twine (NamePrefix) + " .mqsad.pk.fold" );
2667+ case 9 : {
2668+ Value *Accum = emitVectorBuild (B, V4I32 , {A, Bv, C, B.CreateXor (A, Bv)});
2669+ Value *R = B.CreateCall (
2670+ Intrinsic::getOrInsertDeclaration (&M, Intrinsic::amdgcn_mqsad_u32_u8),
2671+ {packI32PairToI64 (B, A, Bv, Twine (NamePrefix) + " .mqsad.a" ), C,
2672+ Accum},
2673+ Twine (NamePrefix) + " .mqsad" );
2674+ return reduceV4I32ToI32 (B, R, Gen, Twine (NamePrefix) + " .mqsad.reduce" );
2675+ }
2676+ case 10 :
25942677 return B.CreateCall (
25952678 Intrinsic::getOrInsertDeclaration (&M, Intrinsic::amdgcn_mul_i24, {I32 }),
25962679 {A, Bv}, Twine (NamePrefix) + " .mul.i24" );
2597- case 8 :
2680+ case 11 :
25982681 return B.CreateCall (
25992682 Intrinsic::getOrInsertDeclaration (&M, Intrinsic::amdgcn_mul_u24, {I32 }),
26002683 {A, Bv}, Twine (NamePrefix) + " .mul.u24" );
2601- case 9 :
2684+ case 12 :
26022685 return B.CreateCall (
26032686 Intrinsic::getOrInsertDeclaration (&M, Intrinsic::amdgcn_mulhi_i24),
26042687 {A, Bv}, Twine (NamePrefix) + " .mulhi.i24" );
2605- case 10 :
2688+ case 13 :
26062689 return B.CreateCall (
26072690 Intrinsic::getOrInsertDeclaration (&M, Intrinsic::amdgcn_mulhi_u24),
26082691 {A, Bv}, Twine (NamePrefix) + " .mulhi.u24" );
2609- case 11 :
2692+ case 14 :
2693+ return B.CreateCall (
2694+ Intrinsic::getOrInsertDeclaration (&M, Intrinsic::amdgcn_alignbyte),
2695+ {A, Bv, B.CreateAnd (C, ci32 (Ctx, 3 ), Twine (NamePrefix) + " .byte" )},
2696+ Twine (NamePrefix) + " .alignbyte" );
2697+ case 15 :
2698+ return B.CreateCall (
2699+ Intrinsic::getOrInsertDeclaration (&M, Intrinsic::amdgcn_sffbh, {I32 }),
2700+ {A}, Twine (NamePrefix) + " .sffbh" );
2701+ case 16 :
2702+ return B.CreateCall (
2703+ Intrinsic::getOrInsertDeclaration (&M, Intrinsic::amdgcn_mbcnt_lo),
2704+ {A, Bv}, Twine (NamePrefix) + " .mbcnt.lo" );
2705+ case 17 :
2706+ return B.CreateCall (
2707+ Intrinsic::getOrInsertDeclaration (&M, Intrinsic::amdgcn_mbcnt_hi),
2708+ {A, Bv}, Twine (NamePrefix) + " .mbcnt.hi" );
2709+ case 18 :
2710+ return B.CreateTrunc (B.CreateCall (Intrinsic::getOrInsertDeclaration (
2711+ &M, Intrinsic::amdgcn_mul_i24, {I64 }),
2712+ {A, Bv},
2713+ Twine (NamePrefix) + " .mul.i24.i64" ),
2714+ I32 , Twine (NamePrefix) + " .mul.i24.i64.trunc" );
2715+ case 19 :
2716+ return B.CreateTrunc (B.CreateCall (Intrinsic::getOrInsertDeclaration (
2717+ &M, Intrinsic::amdgcn_mul_u24, {I64 }),
2718+ {A, Bv},
2719+ Twine (NamePrefix) + " .mul.u24.i64" ),
2720+ I32 , Twine (NamePrefix) + " .mul.u24.i64.trunc" );
2721+ case 20 :
26102722 return B.CreateCall (
26112723 Intrinsic::getOrInsertDeclaration (&M, Intrinsic::amdgcn_perm),
26122724 {A, Bv, C}, Twine (NamePrefix) + " .perm" );
2613- case 12 :
2725+ case 21 :
26142726 return B.CreateCall (
26152727 Intrinsic::getOrInsertDeclaration (&M, Intrinsic::amdgcn_bitop3, {I32 }),
26162728 {A, Bv, C, ci32 (Ctx, Gen () & 255u )},
26172729 Twine (NamePrefix) + " .bitop3" );
2618- case 13 :
2730+ case 22 :
26192731 return B.CreateCall (
26202732 Intrinsic::getOrInsertDeclaration (&M, Intrinsic::amdgcn_sdot2),
26212733 {packI32ToV2I16 (B, A, Twine (NamePrefix) + " .sdot2.a" ),
26222734 packI32ToV2I16 (B, Bv, Twine (NamePrefix) + " .sdot2.b" ), C, Clamp},
26232735 Twine (NamePrefix) + " .sdot2" );
2624- case 14 :
2736+ case 23 :
26252737 return B.CreateCall (
26262738 Intrinsic::getOrInsertDeclaration (&M, Intrinsic::amdgcn_udot2),
26272739 {packI32ToV2I16 (B, A, Twine (NamePrefix) + " .udot2.a" ),
26282740 packI32ToV2I16 (B, Bv, Twine (NamePrefix) + " .udot2.b" ), C, Clamp},
26292741 Twine (NamePrefix) + " .udot2" );
2630- case 15 :
2742+ case 24 :
26312743 return B.CreateCall (
26322744 Intrinsic::getOrInsertDeclaration (&M, Intrinsic::amdgcn_sdot4),
26332745 {A, Bv, C, Clamp}, Twine (NamePrefix) + " .sdot4" );
2634- case 16 :
2746+ case 25 :
26352747 return B.CreateCall (
26362748 Intrinsic::getOrInsertDeclaration (&M, Intrinsic::amdgcn_udot4),
26372749 {A, Bv, C, Clamp}, Twine (NamePrefix) + " .udot4" );
2638- case 17 :
2750+ case 26 :
26392751 if (AllowSUDot)
26402752 return B.CreateCall (
26412753 Intrinsic::getOrInsertDeclaration (&M, Intrinsic::amdgcn_sudot4),
@@ -2645,15 +2757,15 @@ Value *emitRandomAMDGPUIntrinsicInstruction(IRBuilder<NoFolder> &B, Module &M,
26452757 return B.CreateCall (
26462758 Intrinsic::getOrInsertDeclaration (&M, Intrinsic::amdgcn_sdot8),
26472759 {A, Bv, C, Clamp}, Twine (NamePrefix) + " .sdot8" );
2648- case 18 :
2760+ case 27 :
26492761 if (!AllowSUDot)
26502762 return B.CreateCall (
26512763 Intrinsic::getOrInsertDeclaration (&M, Intrinsic::amdgcn_udot8),
26522764 {A, Bv, C, Clamp}, Twine (NamePrefix) + " .udot8" );
26532765 return B.CreateCall (
26542766 Intrinsic::getOrInsertDeclaration (&M, Intrinsic::amdgcn_sdot8),
26552767 {A, Bv, C, Clamp}, Twine (NamePrefix) + " .sdot8" );
2656- case 19 :
2768+ case 28 :
26572769 return B.CreateCall (
26582770 Intrinsic::getOrInsertDeclaration (&M, Intrinsic::amdgcn_udot8),
26592771 {A, Bv, C, Clamp}, Twine (NamePrefix) + " .udot8" );
0 commit comments