/** * Given the i32 or vNi32 \p type, generate the textual name (e.g. for use with * intrinsic names). */ void ac_build_type_name_for_intr(LLVMTypeRef type, char *buf, unsigned bufsize) { LLVMTypeRef elem_type = type; assert(bufsize >= 8); if (LLVMGetTypeKind(type) == LLVMVectorTypeKind) { int ret = snprintf(buf, bufsize, "v%u", LLVMGetVectorSize(type)); if (ret < 0) { char *type_name = LLVMPrintTypeToString(type); fprintf(stderr, "Error building type name for: %s\n", type_name); return; } elem_type = LLVMGetElementType(type); buf += ret; bufsize -= ret; } switch (LLVMGetTypeKind(elem_type)) { default: break; case LLVMIntegerTypeKind: snprintf(buf, bufsize, "i%d", LLVMGetIntTypeWidth(elem_type)); break; case LLVMFloatTypeKind: snprintf(buf, bufsize, "f32"); break; case LLVMDoubleTypeKind: snprintf(buf, bufsize, "f64"); break; } }
/** * Converts int16 half-float to float32 * Note this can be performed in 1 instruction if vcvtph2ps exists (f16c/cvt16) * [llvm.x86.vcvtph2ps / _mm_cvtph_ps] * * @param src value to convert * */ LLVMValueRef lp_build_half_to_float(struct gallivm_state *gallivm, LLVMValueRef src) { LLVMBuilderRef builder = gallivm->builder; LLVMTypeRef src_type = LLVMTypeOf(src); unsigned src_length = LLVMGetTypeKind(src_type) == LLVMVectorTypeKind ? LLVMGetVectorSize(src_type) : 1; struct lp_type f32_type = lp_type_float_vec(32, 32 * src_length); struct lp_type i32_type = lp_type_int_vec(32, 32 * src_length); LLVMTypeRef int_vec_type = lp_build_vec_type(gallivm, i32_type); LLVMValueRef h; if (util_cpu_caps.has_f16c && HAVE_LLVM >= 0x0301 && (src_length == 4 || src_length == 8)) { const char *intrinsic = NULL; if (src_length == 4) { src = lp_build_pad_vector(gallivm, src, 8); intrinsic = "llvm.x86.vcvtph2ps.128"; } else { intrinsic = "llvm.x86.vcvtph2ps.256"; } return lp_build_intrinsic_unary(builder, intrinsic, lp_build_vec_type(gallivm, f32_type), src); } /* Convert int16 vector to int32 vector by zero ext (might generate bad code) */ h = LLVMBuildZExt(builder, src, int_vec_type, ""); return lp_build_smallfloat_to_float(gallivm, f32_type, h, 10, 5, 0, true); }
LLVMValueRef lp_build_intrinsic_map(struct gallivm_state *gallivm, const char *name, LLVMTypeRef ret_type, LLVMValueRef *args, unsigned num_args) { LLVMBuilderRef builder = gallivm->builder; LLVMTypeRef ret_elem_type = LLVMGetElementType(ret_type); unsigned n = LLVMGetVectorSize(ret_type); unsigned i, j; LLVMValueRef res; assert(num_args <= LP_MAX_FUNC_ARGS); res = LLVMGetUndef(ret_type); for(i = 0; i < n; ++i) { LLVMValueRef index = lp_build_const_int32(gallivm, i); LLVMValueRef arg_elems[LP_MAX_FUNC_ARGS]; LLVMValueRef res_elem; for(j = 0; j < num_args; ++j) arg_elems[j] = LLVMBuildExtractElement(builder, args[j], index, ""); res_elem = lp_build_intrinsic(builder, name, ret_elem_type, arg_elems, num_args, 0); res = LLVMBuildInsertElement(builder, res, res_elem, index, ""); } return res; }
LLVMValueRef lp_build_broadcast(struct gallivm_state *gallivm, LLVMTypeRef vec_type, LLVMValueRef scalar) { LLVMValueRef res; if (LLVMGetTypeKind(vec_type) != LLVMVectorTypeKind) { /* scalar */ assert(vec_type == LLVMTypeOf(scalar)); res = scalar; } else { LLVMBuilderRef builder = gallivm->builder; const unsigned length = LLVMGetVectorSize(vec_type); LLVMValueRef undef = LLVMGetUndef(vec_type); /* The shuffle vector is always made of int32 elements */ LLVMTypeRef i32_type = LLVMInt32TypeInContext(gallivm->context); LLVMTypeRef i32_vec_type = LLVMVectorType(i32_type, length); assert(LLVMGetElementType(vec_type) == LLVMTypeOf(scalar)); res = LLVMBuildInsertElement(builder, undef, scalar, LLVMConstNull(i32_type), ""); res = LLVMBuildShuffleVector(builder, res, undef, LLVMConstNull(i32_vec_type), ""); } return res; }
/** * Return the size of the LLVMType in bits. * XXX this function doesn't necessarily handle all LLVM types. */ unsigned lp_sizeof_llvm_type(LLVMTypeRef t) { LLVMTypeKind k = LLVMGetTypeKind(t); switch (k) { case LLVMIntegerTypeKind: return LLVMGetIntTypeWidth(t); case LLVMFloatTypeKind: return 8 * sizeof(float); case LLVMDoubleTypeKind: return 8 * sizeof(double); case LLVMVectorTypeKind: { LLVMTypeRef elem = LLVMGetElementType(t); unsigned len = LLVMGetVectorSize(t); return len * lp_sizeof_llvm_type(elem); } break; case LLVMArrayTypeKind: { LLVMTypeRef elem = LLVMGetElementType(t); unsigned len = LLVMGetArrayLength(t); return len * lp_sizeof_llvm_type(elem); } break; default: assert(0 && "Unexpected type in lp_get_llvm_type_size()"); return 0; } }
void expand_vectors(struct list_t *elem_list) { int index; int vec_index; struct cl2llvm_val_t *cl2llvm_index; struct cl2llvm_val_t *current_vec_elem; struct cl2llvm_val_t *current_elem; LIST_FOR_EACH(elem_list, index) { current_elem = list_get(elem_list, index); if (LLVMGetTypeKind(cl2llvmTypeWrapGetLlvmType(current_elem->type)) == LLVMVectorTypeKind) { for(vec_index = 0; vec_index < LLVMGetVectorSize(cl2llvmTypeWrapGetLlvmType(current_elem->type)); vec_index++) { cl2llvm_index = cl2llvm_val_create_w_init( LLVMConstInt( LLVMInt32Type(), vec_index, 0), 1); snprintf(temp_var_name, sizeof(temp_var_name), "tmp_%d", temp_var_count++); current_vec_elem = cl2llvm_val_create_w_init( LLVMBuildExtractElement(cl2llvm_builder, current_elem->val, cl2llvm_index->val, temp_var_name), cl2llvmTypeWrapGetSign(current_elem->type)); list_insert(elem_list, index + vec_index, current_vec_elem); cl2llvm_val_free(cl2llvm_index); } cl2llvm_val_free(current_elem); list_remove(elem_list, current_elem); } }
/** * Print a LLVM value of any type */ LLVMValueRef lp_build_print_value(struct gallivm_state *gallivm, const char *msg, LLVMValueRef value) { LLVMBuilderRef builder = gallivm->builder; LLVMTypeKind type_kind; LLVMTypeRef type_ref; LLVMValueRef params[2 + LP_MAX_VECTOR_LENGTH]; char type_fmt[4] = " %x"; char format[2 + 3 * LP_MAX_VECTOR_LENGTH + 2] = "%s"; unsigned length; unsigned i; type_ref = LLVMTypeOf(value); type_kind = LLVMGetTypeKind(type_ref); if (type_kind == LLVMVectorTypeKind) { length = LLVMGetVectorSize(type_ref); type_ref = LLVMGetElementType(type_ref); type_kind = LLVMGetTypeKind(type_ref); } else { length = 1; } if (type_kind == LLVMFloatTypeKind || type_kind == LLVMDoubleTypeKind) { type_fmt[2] = 'f'; } else if (type_kind == LLVMIntegerTypeKind) { if (LLVMGetIntTypeWidth(type_ref) == 8) { type_fmt[2] = 'u'; } else { type_fmt[2] = 'i'; } } else { /* Unsupported type */ assert(0); } /* Create format string and arguments */ assert(strlen(format) + strlen(type_fmt) * length + 2 <= sizeof format); params[1] = lp_build_const_string(gallivm, msg); if (length == 1) { util_strncat(format, type_fmt, sizeof(format) - strlen(format) - 1); params[2] = value; } else { for (i = 0; i < length; ++i) { util_strncat(format, type_fmt, sizeof(format) - strlen(format) - 1); params[2 + i] = LLVMBuildExtractElement(builder, value, lp_build_const_int32(gallivm, i), ""); } } util_strncat(format, "\n", sizeof(format) - strlen(format) - 1); params[0] = lp_build_const_string(gallivm, format); return lp_build_print_args(gallivm, 2 + length, params); }
static LLVMValueRef bitcast_to_float(struct ac_llvm_context *ctx, LLVMValueRef value) { LLVMTypeRef type = LLVMTypeOf(value); LLVMTypeRef new_type; if (LLVMGetTypeKind(type) == LLVMVectorTypeKind) new_type = LLVMVectorType(ctx->f32, LLVMGetVectorSize(type)); else new_type = ctx->f32; return LLVMBuildBitCast(ctx->builder, value, new_type, ""); }
void lp_format_intrinsic(char *name, size_t size, const char *name_root, LLVMTypeRef type) { unsigned length = 0; unsigned width; char c; LLVMTypeKind kind = LLVMGetTypeKind(type); if (kind == LLVMVectorTypeKind) { length = LLVMGetVectorSize(type); type = LLVMGetElementType(type); kind = LLVMGetTypeKind(type); } switch (kind) { case LLVMIntegerTypeKind: c = 'i'; width = LLVMGetIntTypeWidth(type); break; case LLVMFloatTypeKind: c = 'f'; width = 32; break; case LLVMDoubleTypeKind: c = 'f'; width = 64; break; default: unreachable("unexpected LLVMTypeKind"); } if (length) { util_snprintf(name, size, "%s.v%u%c%u", name_root, length, c, width); } else { util_snprintf(name, size, "%s.%c%u", name_root, c, width); } }
boolean lp_check_vec_type(struct lp_type type, LLVMTypeRef vec_type) { LLVMTypeRef elem_type; assert(vec_type); if(!vec_type) return FALSE; if (type.length == 1) return lp_check_elem_type(type, vec_type); if(LLVMGetTypeKind(vec_type) != LLVMVectorTypeKind) return FALSE; if(LLVMGetVectorSize(vec_type) != type.length) return FALSE; elem_type = LLVMGetElementType(vec_type); return lp_check_elem_type(type, elem_type); }
/** * Expands src vector from src.length to dst_length */ LLVMValueRef lp_build_pad_vector(struct gallivm_state *gallivm, LLVMValueRef src, unsigned dst_length) { LLVMValueRef elems[LP_MAX_VECTOR_LENGTH]; LLVMValueRef undef; LLVMTypeRef type; unsigned i, src_length; type = LLVMTypeOf(src); if (LLVMGetTypeKind(type) != LLVMVectorTypeKind) { /* Can't use ShuffleVector on non-vector type */ undef = LLVMGetUndef(LLVMVectorType(type, dst_length)); return LLVMBuildInsertElement(gallivm->builder, undef, src, lp_build_const_int32(gallivm, 0), ""); } undef = LLVMGetUndef(type); src_length = LLVMGetVectorSize(type); assert(dst_length <= Elements(elems)); assert(dst_length >= src_length); if (src_length == dst_length) return src; /* All elements from src vector */ for (i = 0; i < src_length; ++i) elems[i] = lp_build_const_int32(gallivm, i); /* Undef fill remaining space */ for (i = src_length; i < dst_length; ++i) elems[i] = lp_build_const_int32(gallivm, src_length); /* Combine the two vectors */ return LLVMBuildShuffleVector(gallivm->builder, src, undef, LLVMConstVector(elems, dst_length), ""); }
LLVMValueRef lp_build_broadcast(struct gallivm_state *gallivm, LLVMTypeRef vec_type, LLVMValueRef scalar) { LLVMValueRef res; if (LLVMGetTypeKind(vec_type) != LLVMVectorTypeKind) { /* scalar */ assert(vec_type == LLVMTypeOf(scalar)); res = scalar; } else { LLVMBuilderRef builder = gallivm->builder; const unsigned length = LLVMGetVectorSize(vec_type); LLVMValueRef undef = LLVMGetUndef(vec_type); LLVMTypeRef i32_type = LLVMInt32TypeInContext(gallivm->context); assert(LLVMGetElementType(vec_type) == LLVMTypeOf(scalar)); if (HAVE_LLVM >= 0x207) { /* The shuffle vector is always made of int32 elements */ LLVMTypeRef i32_vec_type = LLVMVectorType(i32_type, length); res = LLVMBuildInsertElement(builder, undef, scalar, LLVMConstNull(i32_type), ""); res = LLVMBuildShuffleVector(builder, res, undef, LLVMConstNull(i32_vec_type), ""); } else { /* XXX: The above path provokes a bug in LLVM 2.6 */ unsigned i; res = undef; for(i = 0; i < length; ++i) { LLVMValueRef index = lp_build_const_int32(gallivm, i); res = LLVMBuildInsertElement(builder, res, scalar, index, ""); } } } return res; }
/** * Print an LLVMTypeRef. Like LLVMDumpValue(). For debugging. */ void lp_dump_llvmtype(LLVMTypeRef t) { LLVMTypeKind k = LLVMGetTypeKind(t); if (k == LLVMVectorTypeKind) { LLVMTypeRef te = LLVMGetElementType(t); LLVMTypeKind ke = LLVMGetTypeKind(te); unsigned len = LLVMGetVectorSize(t); if (ke == LLVMIntegerTypeKind) { unsigned b = LLVMGetIntTypeWidth(te); debug_printf("Vector [%u] of %u-bit Integer\n", len, b); } else { debug_printf("Vector [%u] of %s\n", len, lp_typekind_name(ke)); } } else if (k == LLVMArrayTypeKind) { LLVMTypeRef te = LLVMGetElementType(t); LLVMTypeKind ke = LLVMGetTypeKind(te); unsigned len = LLVMGetArrayLength(t); debug_printf("Array [%u] of %s\n", len, lp_typekind_name(ke)); } else if (k == LLVMIntegerTypeKind) { unsigned b = LLVMGetIntTypeWidth(t); debug_printf("%u-bit Integer\n", b); } else if (k == LLVMPointerTypeKind) { LLVMTypeRef te = LLVMGetElementType(t); debug_printf("Pointer to "); lp_dump_llvmtype(te); } else { debug_printf("%s\n", lp_typekind_name(k)); } }
/* This function takes cl2llvm_type and an empty string. The string is then filled with the type of the cl2llvm_type */ void cl2llvm_type_to_string(struct cl2llvmTypeWrap *type, char *type_string) { int sign; int i, j; int vec_size; int ptr_count; int array_count; int array_size[50]; char type_string_cpy[50]; LLVMTypeRef bit_type; bit_type = cl2llvmTypeWrapGetLlvmType(type); sign = cl2llvmTypeWrapGetSign(type); array_count = 0; ptr_count = 0; vec_size = 0; /* Get array information */ if (LLVMGetTypeKind(bit_type) == LLVMArrayTypeKind) { for (array_count = 0; LLVMGetTypeKind(bit_type) == LLVMArrayTypeKind; array_count++) { array_size[array_count] = LLVMGetArrayLength(bit_type); bit_type = LLVMGetElementType(bit_type); } } /* Get pointer information */ if (LLVMGetTypeKind(bit_type) == LLVMPointerTypeKind) { for (ptr_count = 0; LLVMGetTypeKind(bit_type) == LLVMPointerTypeKind; ptr_count++) { bit_type = LLVMGetElementType(bit_type); } } /* Get vector information */ if (LLVMGetTypeKind(bit_type) == LLVMVectorTypeKind) { vec_size = LLVMGetVectorSize(bit_type); bit_type = LLVMGetElementType(bit_type); } if (LLVMGetTypeKind(bit_type) == LLVMDoubleTypeKind) strcpy(type_string, "double"); else if (LLVMGetTypeKind(bit_type) == LLVMFloatTypeKind) strcpy(type_string, "float"); else if (LLVMGetTypeKind(bit_type) == LLVMHalfTypeKind) strcpy(type_string, "half"); else if (LLVMGetTypeKind(bit_type) == LLVMIntegerTypeKind) { if (bit_type == LLVMInt64Type()) { if (sign) strcpy(type_string, "long long"); else strcpy(type_string, "unsigned long long"); } else if (bit_type == LLVMInt32Type()) { if (sign) strcpy(type_string, "int"); else strcpy(type_string, "uint"); } else if (bit_type == LLVMInt16Type()) { if (sign) strcpy(type_string, "short"); else strcpy(type_string, "ushort"); } else if (bit_type == LLVMInt8Type()) { if (sign) strcpy(type_string, "char"); else strcpy(type_string, "uchar"); } else if (bit_type == LLVMInt1Type()) strcpy(type_string, "bool"); } if (vec_size) { i = 0; while (type_string[i] != '\00') i++; switch (vec_size) { case 2: type_string[i] = '2'; break; case 3: type_string[i] = '3'; break; case 4: type_string[i] = '4'; break; case 8: type_string[i] = '8'; break; case 16: type_string[i] = '1'; type_string[++i] = '6'; break; } i++; type_string[i] = '\00'; } if (ptr_count) { i = 0; while (type_string[i] != '\00') i++; type_string[i++] = ' '; for (j = 0; j < ptr_count; j++) type_string[i++] = '*'; type_string[i] = '\00'; } if (array_count == 1) { i = 0; while (type_string[i] != '\00') i++; type_string[i] = '*'; i++; type_string[i] = '\00'; } else if (array_count) { i = 0; while (type_string[i] != '\00') i++; type_string[i++] = '('; type_string[i++] = '*'; type_string[i++] = ')'; type_string[i] = '\00'; for (j = 1; j < array_count; j++) { strcpy(type_string_cpy, type_string); snprintf(type_string, sizeof(char) * 40, "%s[%d]", type_string_cpy, array_size[j]); } } }
struct cl2llvm_val_t *llvm_type_cast(struct cl2llvm_val_t * original_val, struct cl2llvmTypeWrap *totype_w_sign) { struct cl2llvm_val_t *llvm_val = cl2llvm_val_create(); int i; struct cl2llvmTypeWrap *elem_type; struct cl2llvm_val_t *cast_original_val; LLVMValueRef index; LLVMValueRef vector_addr; LLVMValueRef vector; LLVMValueRef const_elems[16]; LLVMTypeRef fromtype = cl2llvmTypeWrapGetLlvmType(original_val->type); LLVMTypeRef totype = cl2llvmTypeWrapGetLlvmType(totype_w_sign); int fromsign = cl2llvmTypeWrapGetSign(original_val->type); int tosign = cl2llvmTypeWrapGetSign(totype_w_sign); /*By default the return value is the same as the original_val*/ llvm_val->val = original_val->val; cl2llvmTypeWrapSetLlvmType(llvm_val->type, cl2llvmTypeWrapGetLlvmType(original_val->type)); cl2llvmTypeWrapSetSign(llvm_val->type, cl2llvmTypeWrapGetSign(original_val->type)); snprintf(temp_var_name, sizeof temp_var_name, "tmp_%d", temp_var_count++); /* Check that fromtype is not a vector, unless both types are identical. */ if (LLVMGetTypeKind(fromtype) == LLVMVectorTypeKind) { if ((LLVMGetVectorSize(fromtype) != LLVMGetVectorSize(totype) || LLVMGetElementType(fromtype) != LLVMGetElementType(totype)) || fromsign != tosign) { if (LLVMGetTypeKind(totype) == LLVMVectorTypeKind) cl2llvm_yyerror("Casts between vector types are forbidden"); cl2llvm_yyerror("A vector may not be cast to any other type."); } } /* If totype is a vector, create a vector whose components are equal to original_val */ if (LLVMGetTypeKind(totype) == LLVMVectorTypeKind && LLVMGetTypeKind(fromtype) != LLVMVectorTypeKind) { /*Go to entry block and declare vector*/ LLVMPositionBuilder(cl2llvm_builder, cl2llvm_current_function->entry_block, cl2llvm_current_function->branch_instr); snprintf(temp_var_name, sizeof temp_var_name, "tmp_%d", temp_var_count++); vector_addr = LLVMBuildAlloca(cl2llvm_builder, totype, temp_var_name); LLVMPositionBuilderAtEnd(cl2llvm_builder, current_basic_block); /* Load vector */ snprintf(temp_var_name, sizeof temp_var_name, "tmp_%d", temp_var_count++); vector = LLVMBuildLoad(cl2llvm_builder, vector_addr, temp_var_name); /* Create object to represent element type of totype */ elem_type = cl2llvmTypeWrapCreate(LLVMGetElementType(totype), tosign); /* If original_val is constant create a constant vector */ if (LLVMIsConstant(original_val->val)) { cast_original_val = llvm_type_cast(original_val, elem_type); for (i = 0; i < LLVMGetVectorSize(totype); i++) const_elems[i] = cast_original_val->val; vector = LLVMConstVector(const_elems, LLVMGetVectorSize(totype)); llvm_val->val = vector; cl2llvm_val_free(cast_original_val); } /* If original value is not constant insert elements */ else { for (i = 0; i < LLVMGetVectorSize(totype); i++) { index = LLVMConstInt(LLVMInt32Type(), i, 0); cast_original_val = llvm_type_cast(original_val, elem_type); snprintf(temp_var_name, sizeof temp_var_name, "tmp_%d", temp_var_count++); vector = LLVMBuildInsertElement(cl2llvm_builder, vector, cast_original_val->val, index, temp_var_name); cl2llvm_val_free(cast_original_val); } } cl2llvmTypeWrapFree(elem_type); llvm_val->val = vector; } if (fromtype == LLVMInt64Type()) { if (totype == LLVMDoubleType()) { if (fromsign) { llvm_val->val = LLVMBuildSIToFP(cl2llvm_builder, original_val->val, LLVMDoubleType(), temp_var_name); } else { llvm_val->val = LLVMBuildUIToFP(cl2llvm_builder, original_val->val, LLVMDoubleType(), temp_var_name); } cl2llvmTypeWrapSetSign(llvm_val->type, 1); } else if (totype == LLVMFloatType()) { if (fromsign) { llvm_val->val = LLVMBuildSIToFP(cl2llvm_builder, original_val->val, LLVMFloatType(), temp_var_name); } else { llvm_val->val = LLVMBuildUIToFP(cl2llvm_builder, original_val->val, LLVMFloatType(), temp_var_name); } cl2llvmTypeWrapSetSign(llvm_val->type, 1); } else if (totype == LLVMHalfType()) { if (fromsign) { llvm_val->val = LLVMBuildSIToFP(cl2llvm_builder, original_val->val, LLVMHalfType(), temp_var_name); } else { llvm_val->val = LLVMBuildUIToFP(cl2llvm_builder, original_val->val, LLVMHalfType(), temp_var_name); } cl2llvmTypeWrapSetSign(llvm_val->type, 1); } else if (totype == LLVMInt64Type()) { if (tosign) cl2llvmTypeWrapSetSign(llvm_val->type, 1); else cl2llvmTypeWrapSetSign(llvm_val->type, 0); temp_var_count--; } else if (totype == LLVMInt32Type()) { llvm_val->val = LLVMBuildTrunc(cl2llvm_builder, original_val->val, LLVMInt32Type(), temp_var_name); if(tosign) cl2llvmTypeWrapSetSign(llvm_val->type, 1); else cl2llvmTypeWrapSetSign(llvm_val->type, 0); } else if (totype == LLVMInt16Type()) { llvm_val->val = LLVMBuildTrunc(cl2llvm_builder, original_val->val, LLVMInt16Type(), temp_var_name); if(tosign) cl2llvmTypeWrapSetSign(llvm_val->type, 1); else cl2llvmTypeWrapSetSign(llvm_val->type, 0); } else if (totype == LLVMInt8Type()) { llvm_val->val = LLVMBuildTrunc(cl2llvm_builder, original_val->val, LLVMInt8Type(), temp_var_name); if(tosign) cl2llvmTypeWrapSetSign(llvm_val->type, 1); else cl2llvmTypeWrapSetSign(llvm_val->type, 0); } else if (totype == LLVMInt1Type()) { llvm_val->val = LLVMBuildTrunc(cl2llvm_builder, original_val->val, LLVMInt1Type(), temp_var_name); if(tosign) cl2llvmTypeWrapSetSign(llvm_val->type, 1); else cl2llvmTypeWrapSetSign(llvm_val->type, 0); } } else if (fromtype == LLVMInt32Type()) { if (totype == LLVMDoubleType()) { if (fromsign) { llvm_val->val = LLVMBuildSIToFP(cl2llvm_builder, original_val->val, LLVMDoubleType(), temp_var_name); } else { llvm_val->val = LLVMBuildUIToFP(cl2llvm_builder, original_val->val, LLVMDoubleType(), temp_var_name); } cl2llvmTypeWrapSetSign(llvm_val->type, 1); } else if (totype == LLVMFloatType()) { if (fromsign) { llvm_val->val = LLVMBuildSIToFP(cl2llvm_builder, original_val->val, LLVMFloatType(), temp_var_name); } else { llvm_val->val = LLVMBuildUIToFP(cl2llvm_builder, original_val->val, LLVMFloatType(), temp_var_name); } cl2llvmTypeWrapSetSign(llvm_val->type, 1); } else if (totype == LLVMHalfType()) { if (fromsign) { llvm_val->val = LLVMBuildSIToFP(cl2llvm_builder, original_val->val, LLVMHalfType(), temp_var_name); } else { llvm_val->val = LLVMBuildUIToFP(cl2llvm_builder, original_val->val, LLVMHalfType(), temp_var_name); } cl2llvmTypeWrapSetSign(llvm_val->type, 1); } else if (totype == LLVMInt64Type()) { if (fromsign) { llvm_val->val = LLVMBuildSExt(cl2llvm_builder, original_val->val, LLVMInt64Type(), temp_var_name); } else { llvm_val->val = LLVMBuildZExt(cl2llvm_builder, original_val->val, LLVMInt64Type(), temp_var_name); } if (tosign) cl2llvmTypeWrapSetSign(llvm_val->type, 1); else cl2llvmTypeWrapSetSign(llvm_val->type, 0); } else if (totype == LLVMInt32Type()) { if(tosign) cl2llvmTypeWrapSetSign(llvm_val->type, 1); else cl2llvmTypeWrapSetSign(llvm_val->type, 0); temp_var_count--; } else if (totype == LLVMInt16Type()) { llvm_val->val = LLVMBuildTrunc(cl2llvm_builder, original_val->val, LLVMInt16Type(), temp_var_name); if(tosign) cl2llvmTypeWrapSetSign(llvm_val->type, 1); else cl2llvmTypeWrapSetSign(llvm_val->type, 0); } else if (totype == LLVMInt8Type()) { llvm_val->val = LLVMBuildTrunc(cl2llvm_builder, original_val->val, LLVMInt8Type(), temp_var_name); if(tosign) cl2llvmTypeWrapSetSign(llvm_val->type, 1); else cl2llvmTypeWrapSetSign(llvm_val->type, 0); } else if (totype == LLVMInt1Type()) { llvm_val->val = LLVMBuildTrunc(cl2llvm_builder, original_val->val, LLVMInt1Type(), temp_var_name); if(tosign) cl2llvmTypeWrapSetSign(llvm_val->type, 1); else cl2llvmTypeWrapSetSign(llvm_val->type, 0); } } else if (fromtype == LLVMInt16Type()) { if (totype == LLVMDoubleType()) { if (fromsign) { llvm_val->val = LLVMBuildSIToFP(cl2llvm_builder, original_val->val, LLVMDoubleType(), temp_var_name); } else { llvm_val->val = LLVMBuildUIToFP(cl2llvm_builder, original_val->val, LLVMDoubleType(), temp_var_name); } cl2llvmTypeWrapSetSign(llvm_val->type, 1); } else if (totype == LLVMFloatType()) { if (fromsign) { llvm_val->val = LLVMBuildSIToFP(cl2llvm_builder, original_val->val, LLVMFloatType(), temp_var_name); } else { llvm_val->val = LLVMBuildUIToFP(cl2llvm_builder, original_val->val, LLVMFloatType(), temp_var_name); } cl2llvmTypeWrapSetSign(llvm_val->type, 1); } else if (totype == LLVMHalfType()) { if (fromsign) { llvm_val->val = LLVMBuildSIToFP(cl2llvm_builder, original_val->val, LLVMHalfType(), temp_var_name); } else { llvm_val->val = LLVMBuildUIToFP(cl2llvm_builder, original_val->val, LLVMHalfType(), temp_var_name); } cl2llvmTypeWrapSetSign(llvm_val->type, 1); } else if (totype == LLVMInt64Type()) { if (fromsign) { llvm_val->val = LLVMBuildSExt(cl2llvm_builder, original_val->val, LLVMInt64Type(), temp_var_name); } else { llvm_val->val = LLVMBuildZExt(cl2llvm_builder, original_val->val, LLVMInt64Type(), temp_var_name); } if (tosign) cl2llvmTypeWrapSetSign(llvm_val->type, 1); else cl2llvmTypeWrapSetSign(llvm_val->type, 0); } else if (totype == LLVMInt32Type()) { if (fromsign) { llvm_val->val = LLVMBuildSExt(cl2llvm_builder, original_val->val, LLVMInt32Type(), temp_var_name); } else { llvm_val->val = LLVMBuildZExt(cl2llvm_builder, original_val->val, LLVMInt32Type(), temp_var_name); } if(tosign) cl2llvmTypeWrapSetSign(llvm_val->type, 1); else cl2llvmTypeWrapSetSign(llvm_val->type, 0); } else if (totype == LLVMInt16Type()) { if(tosign) cl2llvmTypeWrapSetSign(llvm_val->type, 1); else cl2llvmTypeWrapSetSign(llvm_val->type, 0); temp_var_count--; } else if (totype == LLVMInt8Type()) { llvm_val->val = LLVMBuildTrunc(cl2llvm_builder, original_val->val, LLVMInt8Type(), temp_var_name); if(tosign) cl2llvmTypeWrapSetSign(llvm_val->type, 1); else cl2llvmTypeWrapSetSign(llvm_val->type, 0); } else if (totype == LLVMInt1Type()) { llvm_val->val = LLVMBuildTrunc(cl2llvm_builder, original_val->val, LLVMInt1Type(), temp_var_name); if(tosign) cl2llvmTypeWrapSetSign(llvm_val->type, 1); else cl2llvmTypeWrapSetSign(llvm_val->type, 0); } } else if (fromtype == LLVMInt8Type()) { if (totype == LLVMDoubleType()) { if (fromsign) { llvm_val->val = LLVMBuildSIToFP(cl2llvm_builder, original_val->val, LLVMDoubleType(), temp_var_name); } else { llvm_val->val = LLVMBuildUIToFP(cl2llvm_builder, original_val->val, LLVMDoubleType(), temp_var_name); } cl2llvmTypeWrapSetSign(llvm_val->type, 1); } else if (totype == LLVMFloatType()) { if (fromsign) { llvm_val->val = LLVMBuildSIToFP(cl2llvm_builder, original_val->val, LLVMFloatType(), temp_var_name); } else { llvm_val->val = LLVMBuildUIToFP(cl2llvm_builder, original_val->val, LLVMFloatType(), temp_var_name); } cl2llvmTypeWrapSetSign(llvm_val->type, 1); } else if (totype == LLVMHalfType()) { if (fromsign) { llvm_val->val = LLVMBuildSIToFP(cl2llvm_builder, original_val->val, LLVMHalfType(), temp_var_name); } else { llvm_val->val = LLVMBuildUIToFP(cl2llvm_builder, original_val->val, LLVMHalfType(), temp_var_name); } cl2llvmTypeWrapSetSign(llvm_val->type, 1); } else if (totype == LLVMInt64Type()) { if (fromsign) { llvm_val->val = LLVMBuildSExt(cl2llvm_builder, original_val->val, LLVMInt64Type(), temp_var_name); } else { llvm_val->val = LLVMBuildZExt(cl2llvm_builder, original_val->val, LLVMInt64Type(), temp_var_name); } if (tosign) cl2llvmTypeWrapSetSign(llvm_val->type, 1); else cl2llvmTypeWrapSetSign(llvm_val->type, 0); } else if (totype == LLVMInt32Type()) { if (fromsign) { llvm_val->val = LLVMBuildSExt(cl2llvm_builder, original_val->val, LLVMInt32Type(), temp_var_name); } else { llvm_val->val = LLVMBuildZExt(cl2llvm_builder, original_val->val, LLVMInt32Type(), temp_var_name); } if(tosign) cl2llvmTypeWrapSetSign(llvm_val->type, 1); else cl2llvmTypeWrapSetSign(llvm_val->type, 0); } else if (totype == LLVMInt16Type()) { if (fromsign) { llvm_val->val = LLVMBuildSExt(cl2llvm_builder, original_val->val, LLVMInt16Type(), temp_var_name); } else { llvm_val->val = LLVMBuildZExt(cl2llvm_builder, original_val->val, LLVMInt16Type(), temp_var_name); } if(tosign) cl2llvmTypeWrapSetSign(llvm_val->type, 1); else cl2llvmTypeWrapSetSign(llvm_val->type, 0); } else if (totype == LLVMInt8Type()) { if(tosign) cl2llvmTypeWrapSetSign(llvm_val->type, 1); else cl2llvmTypeWrapSetSign(llvm_val->type, 0); temp_var_count--; } else if (totype == LLVMInt1Type()) { llvm_val->val = LLVMBuildTrunc(cl2llvm_builder, original_val->val, LLVMInt1Type(), temp_var_name); if(tosign) cl2llvmTypeWrapSetSign(llvm_val->type, 1); else cl2llvmTypeWrapSetSign(llvm_val->type, 0); } } else if (fromtype == LLVMInt1Type()) { if (totype == LLVMDoubleType()) { if (fromsign) { llvm_val->val = LLVMBuildSIToFP(cl2llvm_builder, original_val->val, LLVMDoubleType(), temp_var_name); } else { llvm_val->val = LLVMBuildUIToFP(cl2llvm_builder, original_val->val, LLVMDoubleType(), temp_var_name); } cl2llvmTypeWrapSetSign(llvm_val->type, 1); } else if (totype == LLVMFloatType()) { if (fromsign) { llvm_val->val = LLVMBuildSIToFP(cl2llvm_builder, original_val->val, LLVMFloatType(), temp_var_name); } else { llvm_val->val = LLVMBuildUIToFP(cl2llvm_builder, original_val->val, LLVMFloatType(), temp_var_name); } cl2llvmTypeWrapSetSign(llvm_val->type, 1); } else if (totype == LLVMHalfType()) { if (fromsign) { llvm_val->val = LLVMBuildSIToFP(cl2llvm_builder, original_val->val, LLVMHalfType(), temp_var_name); } else { llvm_val->val = LLVMBuildUIToFP(cl2llvm_builder, original_val->val, LLVMHalfType(), temp_var_name); } cl2llvmTypeWrapSetSign(llvm_val->type, 1); } else if (totype == LLVMInt64Type()) { if (fromsign) { llvm_val->val = LLVMBuildSExt(cl2llvm_builder, original_val->val, LLVMInt64Type(), temp_var_name); } else { llvm_val->val = LLVMBuildZExt(cl2llvm_builder, original_val->val, LLVMInt64Type(), temp_var_name); } if (tosign) cl2llvmTypeWrapSetSign(llvm_val->type, 1); else cl2llvmTypeWrapSetSign(llvm_val->type, 0); } else if (totype == LLVMInt32Type()) { if (fromsign) { llvm_val->val = LLVMBuildSExt(cl2llvm_builder, original_val->val, LLVMInt32Type(), temp_var_name); } else { llvm_val->val = LLVMBuildZExt(cl2llvm_builder, original_val->val, LLVMInt32Type(), temp_var_name); } if(tosign) cl2llvmTypeWrapSetSign(llvm_val->type, 1); else cl2llvmTypeWrapSetSign(llvm_val->type, 0); } else if (totype == LLVMInt16Type()) { if (fromsign) { llvm_val->val = LLVMBuildSExt(cl2llvm_builder, original_val->val, LLVMInt16Type(), temp_var_name); } else { llvm_val->val = LLVMBuildZExt(cl2llvm_builder, original_val->val, LLVMInt16Type(), temp_var_name); } if(tosign) cl2llvmTypeWrapSetSign(llvm_val->type, 1); else cl2llvmTypeWrapSetSign(llvm_val->type, 0); } else if (totype == LLVMInt8Type()) { if (fromsign) { llvm_val->val = LLVMBuildSExt(cl2llvm_builder, original_val->val, LLVMInt8Type(), temp_var_name); } else { llvm_val->val = LLVMBuildZExt(cl2llvm_builder, original_val->val, LLVMInt8Type(), temp_var_name); } if(tosign) cl2llvmTypeWrapSetSign(llvm_val->type, 1); else cl2llvmTypeWrapSetSign(llvm_val->type, 0); } else if (totype == LLVMInt1Type()) { if(tosign) cl2llvmTypeWrapSetSign(llvm_val->type, 1); else cl2llvmTypeWrapSetSign(llvm_val->type, 0); temp_var_count--; } } /*We now know that from type must be a floating point.*/ /*Floating point to signed integer conversions*/ else if (tosign && LLVMGetTypeKind(totype) == 8) { if (totype == LLVMInt64Type()) { llvm_val->val = LLVMBuildFPToSI(cl2llvm_builder, original_val->val, LLVMInt64Type(), temp_var_name); } else if (totype == LLVMInt32Type()) { llvm_val->val = LLVMBuildFPToSI(cl2llvm_builder, original_val->val, LLVMInt32Type(), temp_var_name); } else if (totype == LLVMInt16Type()) { llvm_val->val = LLVMBuildFPToSI(cl2llvm_builder, original_val->val, LLVMInt16Type(), temp_var_name); } else if (totype == LLVMInt8Type()) { llvm_val->val = LLVMBuildFPToSI(cl2llvm_builder, original_val->val, LLVMInt8Type(), temp_var_name); } else if (totype == LLVMInt1Type()) { llvm_val->val = LLVMBuildFPToSI(cl2llvm_builder, original_val->val, LLVMInt1Type(), temp_var_name); } cl2llvmTypeWrapSetSign(llvm_val->type, 1); } /*Floating point to unsigned integer conversions*/ else if (!tosign) { if (totype == LLVMInt64Type()) { llvm_val->val = LLVMBuildFPToUI(cl2llvm_builder, original_val->val, LLVMInt64Type(), temp_var_name); } else if (totype == LLVMInt32Type()) { llvm_val->val = LLVMBuildFPToUI(cl2llvm_builder, original_val->val, LLVMInt32Type(), temp_var_name); } else if (totype == LLVMInt16Type()) { llvm_val->val = LLVMBuildFPToUI(cl2llvm_builder, original_val->val, LLVMInt16Type(), temp_var_name); } else if (totype == LLVMInt8Type()) { llvm_val->val = LLVMBuildFPToUI(cl2llvm_builder, original_val->val, LLVMInt8Type(), temp_var_name); } else if (totype == LLVMInt1Type()) { llvm_val->val = LLVMBuildFPToUI(cl2llvm_builder, original_val->val, LLVMInt1Type(), temp_var_name); } cl2llvmTypeWrapSetSign(llvm_val->type, 0); } else if (totype == LLVMDoubleType()) { llvm_val->val = LLVMBuildFPExt(cl2llvm_builder, original_val->val, LLVMDoubleType(), temp_var_name); cl2llvmTypeWrapSetSign(llvm_val->type, 1); } else if (totype == LLVMFloatType()) { if (fromtype == LLVMDoubleType()) { llvm_val->val = LLVMBuildFPTrunc(cl2llvm_builder, original_val->val, LLVMFloatType(), temp_var_name); } else if (fromtype == LLVMHalfType()) { llvm_val->val = LLVMBuildFPExt(cl2llvm_builder, original_val->val, LLVMFloatType(), temp_var_name); } cl2llvmTypeWrapSetSign(llvm_val->type, 1); } else if (totype == LLVMHalfType()) { llvm_val->val = LLVMBuildFPTrunc(cl2llvm_builder, original_val->val, LLVMHalfType(), temp_var_name); cl2llvmTypeWrapSetSign(llvm_val->type, 1); } cl2llvmTypeWrapSetLlvmType(llvm_val->type, totype); cl2llvmTypeWrapSetSign(llvm_val->type, tosign); return llvm_val; }
/* This function returns an i1 1 if the value is not equal to 0 and an i1 0 if the value is equal to 0. */ struct cl2llvm_val_t *cl2llvm_to_bool_ne_0(struct cl2llvm_val_t *value) { LLVMValueRef const_zero; LLVMValueRef zero_vec[16]; LLVMTypeRef switch_type; int i; int veclength; struct cl2llvm_val_t *bool_val = cl2llvm_val_create_w_init(value->val, cl2llvmTypeWrapGetSign(value->type)); /* if value is i1 no conversion necessary */ if (LLVMTypeOf(value->val) == LLVMInt1Type()) return bool_val; /* If value is a vector create a vector of constant zeros, else create a scalar 0. */ if (LLVMGetTypeKind(cl2llvmTypeWrapGetLlvmType(value->type)) == LLVMVectorTypeKind) { switch_type = LLVMGetElementType(cl2llvmTypeWrapGetLlvmType(value->type)); veclength = LLVMGetVectorSize(cl2llvmTypeWrapGetLlvmType(value->type)); switch (LLVMGetTypeKind(LLVMGetElementType(cl2llvmTypeWrapGetLlvmType(value->type)))) { case LLVMIntegerTypeKind: /* Create zero vector */ for (i = 0; i < veclength; i++) zero_vec[i] = LLVMConstInt(switch_type, 0, 0); break; case LLVMFloatTypeKind: case LLVMDoubleTypeKind: case LLVMHalfTypeKind: /* Create zero vector */ for (i = 0; i < veclength; i++) zero_vec[i] = LLVMConstReal(switch_type, 0); break; default: cl2llvm_yyerror("unreachable code reached"); } const_zero = LLVMConstVector(zero_vec, veclength); } else if (LLVMGetTypeKind(cl2llvmTypeWrapGetLlvmType(value->type)) == LLVMIntegerTypeKind) { const_zero = LLVMConstInt(cl2llvmTypeWrapGetLlvmType(value->type), 0, 0); switch_type = cl2llvmTypeWrapGetLlvmType(value->type); } else if (LLVMGetTypeKind(cl2llvmTypeWrapGetLlvmType(value->type)) == LLVMFloatTypeKind || LLVMGetTypeKind(cl2llvmTypeWrapGetLlvmType(value->type)) == LLVMDoubleTypeKind || LLVMGetTypeKind(cl2llvmTypeWrapGetLlvmType(value->type)) == LLVMHalfTypeKind) { const_zero = LLVMConstReal(cl2llvmTypeWrapGetLlvmType(value->type), 0); switch_type = cl2llvmTypeWrapGetLlvmType(value->type); } /* Create comparison */ snprintf(temp_var_name, sizeof temp_var_name, "tmp_%d", temp_var_count++); switch (LLVMGetTypeKind(switch_type)) { case LLVMFloatTypeKind: case LLVMDoubleTypeKind: case LLVMHalfTypeKind: bool_val->val = LLVMBuildFCmp(cl2llvm_builder, LLVMRealONE, value->val, const_zero, temp_var_name); break; case LLVMIntegerTypeKind: bool_val->val = LLVMBuildICmp(cl2llvm_builder, LLVMIntNE, value->val, const_zero, temp_var_name); break; default: cl2llvm_yyerror("unreachable code reached"); break; } cl2llvmTypeWrapSetLlvmType(bool_val->type, LLVMInt1Type()); cl2llvmTypeWrapSetSign(bool_val->type, 0); return bool_val; }
/** * Converts float32 to int16 half-float * Note this can be performed in 1 instruction if vcvtps2ph exists (f16c/cvt16) * [llvm.x86.vcvtps2ph / _mm_cvtps_ph] * * @param src value to convert * * Convert float32 to half floats, preserving Infs and NaNs, * with rounding towards zero (trunc). */ LLVMValueRef lp_build_float_to_half(struct gallivm_state *gallivm, LLVMValueRef src) { LLVMBuilderRef builder = gallivm->builder; LLVMTypeRef f32_vec_type = LLVMTypeOf(src); unsigned length = LLVMGetTypeKind(f32_vec_type) == LLVMVectorTypeKind ? LLVMGetVectorSize(f32_vec_type) : 1; struct lp_type i32_type = lp_type_int_vec(32, 32 * length); struct lp_type i16_type = lp_type_int_vec(16, 16 * length); LLVMValueRef result; if (util_cpu_caps.has_f16c && HAVE_LLVM >= 0x0301 && (length == 4 || length == 8)) { struct lp_type i168_type = lp_type_int_vec(16, 16 * 8); unsigned mode = 3; /* same as LP_BUILD_ROUND_TRUNCATE */ LLVMTypeRef i32t = LLVMInt32TypeInContext(gallivm->context); const char *intrinsic = NULL; if (length == 4) { intrinsic = "llvm.x86.vcvtps2ph.128"; } else { intrinsic = "llvm.x86.vcvtps2ph.256"; } result = lp_build_intrinsic_binary(builder, intrinsic, lp_build_vec_type(gallivm, i168_type), src, LLVMConstInt(i32t, mode, 0)); if (length == 4) { result = lp_build_extract_range(gallivm, result, 0, 4); } } else { result = lp_build_float_to_smallfloat(gallivm, i32_type, src, 10, 5, 0, true); /* Convert int32 vector to int16 vector by trunc (might generate bad code) */ result = LLVMBuildTrunc(builder, result, lp_build_vec_type(gallivm, i16_type), ""); } /* * Debugging code. */ if (0) { LLVMTypeRef i32t = LLVMInt32TypeInContext(gallivm->context); LLVMTypeRef i16t = LLVMInt16TypeInContext(gallivm->context); LLVMTypeRef f32t = LLVMFloatTypeInContext(gallivm->context); LLVMValueRef ref_result = LLVMGetUndef(LLVMVectorType(i16t, length)); unsigned i; LLVMTypeRef func_type = LLVMFunctionType(i16t, &f32t, 1, 0); LLVMValueRef func = lp_build_const_int_pointer(gallivm, func_to_pointer((func_pointer)util_float_to_half)); func = LLVMBuildBitCast(builder, func, LLVMPointerType(func_type, 0), "util_float_to_half"); for (i = 0; i < length; ++i) { LLVMValueRef index = LLVMConstInt(i32t, i, 0); LLVMValueRef f32 = LLVMBuildExtractElement(builder, src, index, ""); #if 0 /* XXX: not really supported by backends */ LLVMValueRef f16 = lp_build_intrinsic_unary(builder, "llvm.convert.to.fp16", i16t, f32); #else LLVMValueRef f16 = LLVMBuildCall(builder, func, &f32, 1, ""); #endif ref_result = LLVMBuildInsertElement(builder, ref_result, f16, index, ""); } lp_build_print_value(gallivm, "src = ", src); lp_build_print_value(gallivm, "llvm = ", result); lp_build_print_value(gallivm, "util = ", ref_result); lp_build_printf(gallivm, "\n"); } return result; }
/* This function will take a bool and sign extend it to a specified bitwidth. It will also perform i1 to floating point conversions if necessary. All vector components that are equal to 1 will be converted to -1 in accordance with the OpenCL standard. */ struct cl2llvm_val_t *cl2llvm_bool_ext(struct cl2llvm_val_t *bool_val, struct cl2llvmTypeWrap *type) { struct cl2llvm_val_t *value; struct cl2llvmTypeWrap *switch_type; LLVMTypeRef totype; int vec_length; switch_type = cl2llvmTypeWrapCreate(cl2llvmTypeWrapGetLlvmType(type), cl2llvmTypeWrapGetSign(type)); if (LLVMGetTypeKind(cl2llvmTypeWrapGetLlvmType(type)) == LLVMVectorTypeKind) cl2llvmTypeWrapSetLlvmType(switch_type, LLVMGetElementType(cl2llvmTypeWrapGetLlvmType(type))); if (LLVMGetTypeKind(cl2llvmTypeWrapGetLlvmType(type)) == LLVMVectorTypeKind) { vec_length = LLVMGetVectorSize(cl2llvmTypeWrapGetLlvmType(type)); switch (LLVMGetTypeKind(cl2llvmTypeWrapGetLlvmType(switch_type))) { case LLVMIntegerTypeKind: totype = cl2llvmTypeWrapGetLlvmType(type); break; case LLVMFloatTypeKind: totype = LLVMVectorType(LLVMInt32Type(), vec_length); break; case LLVMDoubleTypeKind: totype = LLVMVectorType(LLVMInt64Type(), vec_length); break; case LLVMHalfTypeKind: totype = LLVMVectorType(LLVMInt16Type(), vec_length); break; default: cl2llvm_yyerror("unreachable code reached"); break; } } else totype = LLVMInt32Type(); value = cl2llvm_val_create(); snprintf(temp_var_name, sizeof temp_var_name, "tmp_%d", temp_var_count++); /* Build sign extension */ value->val = LLVMBuildSExt(cl2llvm_builder, bool_val->val, totype, temp_var_name); cl2llvmTypeWrapSetLlvmType(value->type, totype); cl2llvmTypeWrapSetSign(value->type, 1); /* if value is a vector, change 1's to -1's */ if (LLVMGetTypeKind(cl2llvmTypeWrapGetLlvmType(type)) == LLVMVectorTypeKind) { snprintf(temp_var_name, sizeof temp_var_name, "tmp_%d", temp_var_count++); value->val = LLVMBuildNeg(cl2llvm_builder, value->val, temp_var_name); } cl2llvmTypeWrapFree(switch_type); return value; }