authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-01-27 21:36:43-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-01-28 11:45:04-07:00
log3c827be876a39cbe199e5cd7c6e90edef3a090b5
treed13e5cec6df861361d523201ed922c5f6010af71
parent4411f9c019f8f41baeacd39be01af9f961df4e4e

fix invalid const bitcast of f80

LLVM bitcast wants integers that match the number of bits. So the const bitcast has to use an i80, not an i128. This commit makes the behavior tests fail for me, so it seems I did not correctly construct the type. But it gets rid of the LLVM segfault. I noticed that the strategy of memcpy the buf worked if I simply did an LLVMConstTrunc() on the i128 to make it into an i80 before the LLVMConstBitCast(). But is that correct in the face of different endianness? I'm not sure.

1 files changed, 12 insertions(+), 4 deletions(-)

src/stage1/codegen.cpp+12-4
...@@ -8094,10 +8094,18 @@ static LLVMValueRef gen_const_val(CodeGen *g, ZigValue *const_val, const char *n...@@ -8094,10 +8094,18 @@ static LLVMValueRef gen_const_val(CodeGen *g, ZigValue *const_val, const char *n
8094 case 64:8094 case 64:
8095 return LLVMConstReal(get_llvm_type(g, type_entry), const_val->data.x_f64);8095 return LLVMConstReal(get_llvm_type(g, type_entry), const_val->data.x_f64);
8096 case 80: {8096 case 80: {
8097 uint64_t buf[2];8097 LLVMTypeRef llvm_i80 = LLVMIntType(80);
8098 memcpy(&buf, &const_val->data.x_f80, 16);8098 LLVMValueRef x;
8099 LLVMValueRef as_int = LLVMConstIntOfArbitraryPrecision(LLVMInt128Type(), 2, buf);8099 if (g->is_big_endian) {
8100 return LLVMConstBitCast(as_int, get_llvm_type(g, type_entry));8100 x = LLVMConstInt(llvm_i80, const_val->data.x_f80.signExp, false);
8101 x = LLVMConstShl(x, LLVMConstInt(llvm_i80, 64, false));
8102 x = LLVMConstOr(x, LLVMConstInt(llvm_i80, const_val->data.x_f80.signif, false));
8103 } else {
8104 x = LLVMConstInt(llvm_i80, const_val->data.x_f80.signif, false);
8105 x = LLVMConstShl(x, LLVMConstInt(llvm_i80, 16, false));
8106 x = LLVMConstOr(x, LLVMConstInt(llvm_i80, const_val->data.x_f80.signExp, false));
8107 }
8108 return LLVMConstBitCast(x, get_llvm_type(g, type_entry));
8101 }8109 }
8102 case 128:8110 case 128:
8103 {8111 {