diff options
| author | gingerBill <bill@gingerbill.org> | 2021-03-29 23:15:31 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2021-03-29 23:15:31 +0100 |
| commit | 439e2c92426c59f84d51bfb594e9ac86d496c708 (patch) | |
| tree | 1c2095758e9b8ff910f030ec5a6bf2248c85049a /src/llvm_backend.cpp | |
| parent | 6fb086851782c23e0b6d1f5f708b1b1b4c3ef29d (diff) | |
Fix shifting limits and LLVM code gen bug relating to shifts
Diffstat (limited to 'src/llvm_backend.cpp')
| -rw-r--r-- | src/llvm_backend.cpp | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 14a49b7da..92b180f73 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -6599,13 +6599,14 @@ handle_op: LLVMValueRef lhsval = lhs.value; LLVMValueRef bits = rhs.value; - LLVMValueRef max = LLVMConstInt(lb_type(p->module, rhs.type), 8*type_size_of(lhs.type), false); + LLVMValueRef bit_size = LLVMConstInt(lb_type(p->module, rhs.type), 8*type_size_of(lhs.type), false); + LLVMValueRef max = LLVMConstInt(lb_type(p->module, rhs.type), 8*type_size_of(lhs.type)-1, false); - LLVMValueRef less_equal_width = LLVMBuildICmp(p->builder, LLVMIntULT, bits, max, ""); + LLVMValueRef width_test = LLVMBuildICmp(p->builder, LLVMIntULT, bits, bit_size, ""); res.value = LLVMBuildShl(p->builder, lhsval, bits, ""); LLVMValueRef zero = LLVMConstNull(lb_type(p->module, lhs.type)); - res.value = LLVMBuildSelect(p->builder, less_equal_width, res.value, zero, ""); + res.value = LLVMBuildSelect(p->builder, width_test, res.value, zero, ""); return res; } case Token_Shr: @@ -6615,11 +6616,12 @@ handle_op: LLVMValueRef bits = rhs.value; bool is_unsigned = is_type_unsigned(type); - LLVMValueRef max = LLVMConstInt(lb_type(p->module, rhs.type), 8*type_size_of(lhs.type), false); + LLVMValueRef bit_size = LLVMConstInt(lb_type(p->module, rhs.type), 8*type_size_of(lhs.type), false); + LLVMValueRef max = LLVMConstInt(lb_type(p->module, rhs.type), 8*type_size_of(lhs.type)-1, false); - LLVMValueRef less_equal_width = LLVMBuildICmp(p->builder, LLVMIntULT, bits, max, ""); + LLVMValueRef width_test = LLVMBuildICmp(p->builder, LLVMIntULT, bits, bit_size, ""); - bits = LLVMBuildSelect(p->builder, less_equal_width, bits, max, ""); + bits = LLVMBuildSelect(p->builder, width_test, bits, max, ""); if (is_unsigned) { res.value = LLVMBuildLShr(p->builder, lhs.value, bits, ""); } else { |