LLVMBuildStore(builder, dst[i], ptr);
}
- LLVMBuildRetVoid(builder);;
+ LLVMBuildRetVoid(builder);
+
+ gallivm_verify_function(gallivm, func);
return func;
}
PIPE_ALIGN_STACK
static boolean
-test_one(struct gallivm_state *gallivm, unsigned verbose,
+test_one(unsigned verbose,
FILE *fp,
struct lp_type src_type,
struct lp_type dst_type)
{
- LLVMModuleRef module = gallivm->module;
- LLVMExecutionEngineRef engine = gallivm->engine;
+ LLVMContextRef context;
+ struct gallivm_state *gallivm;
LLVMValueRef func = NULL;
- char *error = NULL;
conv_test_ptr_t conv_test_ptr;
boolean success;
const unsigned n = LP_TEST_NUM_SAMPLES;
unsigned num_dsts;
double eps;
unsigned i, j;
- void *code;
- if (src_type.width * src_type.length != dst_type.width * dst_type.length &&
- src_type.length != dst_type.length) {
+ if ((src_type.width >= dst_type.width && src_type.length > dst_type.length) ||
+ (src_type.width <= dst_type.width && src_type.length < dst_type.length)) {
+ return TRUE;
+ }
+
+ /* Known failures
+ * - fixed point 32 -> float 32
+ * - float 32 -> signed normalised integer 32
+ */
+ if ((src_type.floating && !dst_type.floating && dst_type.sign && dst_type.norm && src_type.width == dst_type.width) ||
+ (!src_type.floating && dst_type.floating && src_type.fixed && src_type.width == dst_type.width)) {
+ return TRUE;
+ }
+
+ /* Known failures
+ * - fixed point 32 -> float 32
+ * - float 32 -> signed normalised integer 32
+ */
+ if ((src_type.floating && !dst_type.floating && dst_type.sign && dst_type.norm && src_type.width == dst_type.width) ||
+ (!src_type.floating && dst_type.floating && src_type.fixed && src_type.width == dst_type.width)) {
return TRUE;
}
if(verbose >= 1)
- dump_conv_types(stdout, src_type, dst_type);
+ dump_conv_types(stderr, src_type, dst_type);
if (src_type.length > dst_type.length) {
num_srcs = 1;
assert(src_type.length * num_srcs == dst_type.length * num_dsts);
eps = MAX2(lp_const_eps(src_type), lp_const_eps(dst_type));
+ if (dst_type.norm && dst_type.sign && src_type.sign && !src_type.floating) {
+ /*
+ * This is quite inaccurate due to shift being used.
+ * I don't think it's possible to hit such conversions with
+ * llvmpipe though.
+ */
+ eps *= 2;
+ }
- func = add_conv_test(gallivm, src_type, num_srcs, dst_type, num_dsts);
+ context = LLVMContextCreate();
+ gallivm = gallivm_create("test_module", context);
- if(LLVMVerifyModule(module, LLVMPrintMessageAction, &error)) {
- LLVMDumpModule(module);
- abort();
- }
- LLVMDisposeMessage(error);
+ func = add_conv_test(gallivm, src_type, num_srcs, dst_type, num_dsts);
- if(verbose >= 2)
- LLVMDumpModule(module);
+ gallivm_compile_module(gallivm);
- code = LLVMGetPointerToGlobal(engine, func);
- conv_test_ptr = (conv_test_ptr_t)pointer_to_func(code);
+ conv_test_ptr = (conv_test_ptr_t)gallivm_jit_function(gallivm, func);
- if(verbose >= 2)
- lp_disassemble(code);
+ gallivm_free_ir(gallivm);
success = TRUE;
for(i = 0; i < n && success; ++i) {
unsigned src_stride = src_type.length*src_type.width/8;
unsigned dst_stride = dst_type.length*dst_type.width/8;
- PIPE_ALIGN_VAR(16) uint8_t src[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH];
- PIPE_ALIGN_VAR(16) uint8_t dst[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH];
+ PIPE_ALIGN_VAR(LP_MIN_VECTOR_ALIGN) uint8_t src[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH];
+ PIPE_ALIGN_VAR(LP_MIN_VECTOR_ALIGN) uint8_t dst[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH];
double fref[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH];
uint8_t ref[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH];
int64_t start_counter = 0;
if(fp)
write_tsv_row(fp, src_type, dst_type, cycles_avg, success);
- if (!success) {
- static boolean firsttime = TRUE;
- if(firsttime) {
- if(verbose < 2)
- LLVMDumpModule(module);
- LLVMWriteBitcodeToFile(module, "conv.bc");
- fprintf(stderr, "conv.bc written\n");
- fprintf(stderr, "Invoke as \"llc -o - conv.bc\"\n");
- firsttime = FALSE;
- /* abort(); */
- }
- }
-
- LLVMFreeMachineCodeForFunction(engine, func);
+ gallivm_destroy(gallivm);
+ LLVMContextDispose(context);
return success;
}
{ TRUE, FALSE, FALSE, TRUE, 32, 4 },
{ TRUE, FALSE, FALSE, FALSE, 32, 4 },
+ { TRUE, FALSE, TRUE, TRUE, 32, 8 },
+ { TRUE, FALSE, TRUE, FALSE, 32, 8 },
+ { TRUE, FALSE, FALSE, TRUE, 32, 8 },
+ { TRUE, FALSE, FALSE, FALSE, 32, 8 },
+
/* Fixed */
{ FALSE, TRUE, TRUE, TRUE, 32, 4 },
{ FALSE, TRUE, TRUE, FALSE, 32, 4 },
{ FALSE, TRUE, FALSE, TRUE, 32, 4 },
{ FALSE, TRUE, FALSE, FALSE, 32, 4 },
+ { FALSE, TRUE, TRUE, TRUE, 32, 8 },
+ { FALSE, TRUE, TRUE, FALSE, 32, 8 },
+ { FALSE, TRUE, FALSE, TRUE, 32, 8 },
+ { FALSE, TRUE, FALSE, FALSE, 32, 8 },
+
/* Integer */
{ FALSE, FALSE, TRUE, TRUE, 32, 4 },
{ FALSE, FALSE, TRUE, FALSE, 32, 4 },
{ FALSE, FALSE, FALSE, TRUE, 32, 4 },
{ FALSE, FALSE, FALSE, FALSE, 32, 4 },
+ { FALSE, FALSE, TRUE, TRUE, 32, 8 },
+ { FALSE, FALSE, TRUE, FALSE, 32, 8 },
+ { FALSE, FALSE, FALSE, TRUE, 32, 8 },
+ { FALSE, FALSE, FALSE, FALSE, 32, 8 },
+
{ FALSE, FALSE, TRUE, TRUE, 16, 8 },
{ FALSE, FALSE, TRUE, FALSE, 16, 8 },
{ FALSE, FALSE, FALSE, TRUE, 16, 8 },
{ FALSE, FALSE, TRUE, FALSE, 8, 4 },
{ FALSE, FALSE, FALSE, TRUE, 8, 4 },
{ FALSE, FALSE, FALSE, FALSE, 8, 4 },
+
+ { FALSE, FALSE, FALSE, TRUE, 8, 8 },
};
-const unsigned num_types = sizeof(conv_types)/sizeof(conv_types[0]);
+const unsigned num_types = ARRAY_SIZE(conv_types);
boolean
-test_all(struct gallivm_state *gallivm, unsigned verbose, FILE *fp)
+test_all(unsigned verbose, FILE *fp)
{
const struct lp_type *src_type;
const struct lp_type *dst_type;
boolean success = TRUE;
+ int error_count = 0;
for(src_type = conv_types; src_type < &conv_types[num_types]; ++src_type) {
for(dst_type = conv_types; dst_type < &conv_types[num_types]; ++dst_type) {
if(src_type == dst_type)
continue;
- if(src_type->norm != dst_type->norm)
- continue;
-
- if(!test_one(gallivm, verbose, fp, *src_type, *dst_type))
- success = FALSE;
-
+ if(!test_one(verbose, fp, *src_type, *dst_type)){
+ success = FALSE;
+ ++error_count;
+ }
}
}
+ fprintf(stderr, "%d failures\n", error_count);
+
return success;
}
boolean
-test_some(struct gallivm_state *gallivm, unsigned verbose, FILE *fp,
+test_some(unsigned verbose, FILE *fp,
unsigned long n)
{
const struct lp_type *src_type;
dst_type = &conv_types[rand() % num_types];
} while (src_type == dst_type || src_type->norm != dst_type->norm);
- if(!test_one(gallivm, verbose, fp, *src_type, *dst_type))
+ if(!test_one(verbose, fp, *src_type, *dst_type))
success = FALSE;
}
boolean
-test_single(struct gallivm_state *gallivm, unsigned verbose, FILE *fp)
+test_single(unsigned verbose, FILE *fp)
{
/* float, fixed, sign, norm, width, len */
struct lp_type f32x4_type =
boolean success;
- success = test_one(gallivm, verbose, fp, f32x4_type, ub8x4_type);
+ success = test_one(verbose, fp, f32x4_type, ub8x4_type);
return success;
}