Skip to content

Commit 9b4bf7c

Browse files
author
LU-JOHN
authored
[SYCL][E2E] Ensure lowering of llvm.bitreverse for 2/4-bit scalars is functionally correct (#13359)
Ensure that lowering of llvm.bitreverse.i2/i4 by llvm-spirv is functionally correct. --------- Signed-off-by: Lu, John <[email protected]>
1 parent 306e5ff commit 9b4bf7c

File tree

1 file changed

+121
-0
lines changed

1 file changed

+121
-0
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
// Test that llvm.bitreverse is lowered correctly by llvm-spirv for 2/4-bit
2+
// types.
3+
4+
// UNSUPPORTED: hip || cuda
5+
6+
// TODO: Remove XFAIL after fixing
7+
// https://github.com/intel/intel-graphics-compiler/issues/330
8+
// XFAIL: gpu
9+
10+
// Make dump directory.
11+
// RUN: rm -rf %t.spvdir && mkdir %t.spvdir
12+
13+
// Ensure that SPV_KHR_bit_instructions is disabled so that translator
14+
// will lower llvm.bitreverse.* intrinsics instead of relying on SPIRV
15+
// BitReverse instruction.
16+
// Also build executable with SPV dump.
17+
// RUN: %{build} -o %t.out -O2 -Xspirv-translator --spirv-ext=-SPV_KHR_bit_instructions -fsycl-dump-device-code=%t.spvdir
18+
19+
// Rename SPV file to explictly known filename.
20+
// RUN: mv %t.spvdir/*.spv %t.spvdir/dump.spv
21+
22+
// Convert to text.
23+
// RUN: llvm-spirv -to-text %t.spvdir/dump.spv
24+
25+
// Check that all lowerings are done by llvm-spirv.
26+
// RUN: cat %t.spvdir/dump.spt | FileCheck %s --check-prefix CHECK-SPV --implicit-check-not=BitReverse
27+
28+
// Execute to ensure lowering has correct functionality.
29+
// RUN: %{run} %t.out
30+
31+
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
32+
33+
// Build without lowering explicitly disabled.
34+
// RUN: %{build} -o %t.bitinstructions.out
35+
36+
// Execution should still be correct.
37+
// RUN: %{run} %t.bitinstructions.out
38+
39+
// CHECK-SPV: Name {{[0-9]+}} "llvm_bitreverse_i2"
40+
// CHECK-SPV: Name {{[0-9]+}} "llvm_bitreverse_i4"
41+
42+
// CHECK-SPV: LinkageAttributes "llvm_bitreverse_i2" Export
43+
// CHECK-SPV: LinkageAttributes "llvm_bitreverse_i4" Export
44+
45+
#include "common.hpp"
46+
#include <iostream>
47+
#include <string.h>
48+
#include <sycl/sycl.hpp>
49+
50+
using namespace sycl;
51+
52+
template <typename TYPE>
53+
__attribute__((optnone, noinline)) TYPE reference_reverse(TYPE a,
54+
const int bitlength) {
55+
TYPE ret = 0;
56+
for (auto i = 0; i < bitlength; i++) {
57+
ret <<= 1;
58+
ret |= a & 0x1;
59+
a >>= 1;
60+
}
61+
return ret;
62+
}
63+
64+
template <typename TYPE>
65+
__attribute__((noinline)) TYPE reverse(TYPE a, int bitlength) {
66+
return __builtin_elementwise_bitreverse(a);
67+
}
68+
69+
template <class T> class BitreverseTest;
70+
71+
#define NUM_TESTS 1024
72+
73+
template <typename TYPE> void do_scalar_bitreverse_test() {
74+
queue q;
75+
76+
// calculate bitlength
77+
int bitlength = 0;
78+
TYPE t = 1;
79+
do {
80+
++bitlength;
81+
t <<= 1;
82+
} while (t);
83+
84+
TYPE *Input = (TYPE *)malloc_shared(sizeof(TYPE) * NUM_TESTS, q.get_device(),
85+
q.get_context());
86+
TYPE *Output = (TYPE *)malloc_shared(sizeof(TYPE) * NUM_TESTS, q.get_device(),
87+
q.get_context());
88+
89+
for (unsigned i = 0; i < NUM_TESTS; i++)
90+
Input[i] = get_rand<TYPE>();
91+
q.submit([=](handler &cgh) {
92+
cgh.single_task<BitreverseTest<TYPE>>([=]() {
93+
for (unsigned i = 0; i < NUM_TESTS; i++)
94+
Output[i] = reverse(Input[i], sizeof(TYPE) * 8);
95+
});
96+
});
97+
q.wait();
98+
for (unsigned i = 0; i < NUM_TESTS; i++)
99+
if (Output[i] != reference_reverse(Input[i], bitlength)) {
100+
std::cerr << "Failed for scalar " << std::hex
101+
<< static_cast<uint64_t>(Input[i]) << " bitlength=" << bitlength
102+
<< "\n";
103+
104+
exit(-1);
105+
}
106+
107+
free(Input, q.get_context());
108+
free(Output, q.get_context());
109+
}
110+
111+
using uint2_t = _BitInt(2);
112+
using uint4_t = _BitInt(4);
113+
114+
int main() {
115+
srand(2024);
116+
117+
do_scalar_bitreverse_test<uint2_t>();
118+
do_scalar_bitreverse_test<uint4_t>();
119+
120+
return 0;
121+
}

0 commit comments

Comments
 (0)