Skip to content

Commit fc0f7f6

Browse files
committed
Expand AMDGPU packed integer intrinsic fuzzing
1 parent 849b0bd commit fc0f7f6

2 files changed

Lines changed: 129 additions & 16 deletions

File tree

‎amdgpu/README.md‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,10 @@ reduced back to `i32`, explicit `i1` boolean subexpressions reduced back to
5252
`i32`, and LLVM bit, min/max, saturation, absolute-value, funnel-shift, and
5353
integer overflow intrinsics. It also emits a small AMDGPU-specific pure
5454
integer-intrinsic subset covering BFE, SAD/MSAD, `lerp`, 24-bit multiply,
55-
`perm`, explicit `bitop3`, and integer dot-product operations, with known
56-
`sudot*` instruction-selection crashes gated off by default. It also emits a
57-
finite scalar FP subset by masking
55+
packed SAD/MQSAD, `alignbyte`, signed first-bit-high, `mbcnt`, `perm`,
56+
explicit `bitop3`, and integer dot-product operations, with known `sudot*`
57+
instruction-selection crashes gated off by default. It also emits a finite
58+
scalar FP subset by masking
5859
inputs to small nonnegative integers, converting with `uitofp`, using exact
5960
`fadd` / `fmul` / `fcmp` / `select` shapes, and converting back with in-range
6061
`fptoui`; a signed variant uses small sign-extended integers, `sitofp`,

‎amdgpu/fuzzer/llvm_amdgpu_diff_fuzzer.cpp‎

Lines changed: 125 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
25462594
Value *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

Comments
 (0)