From 439e2c92426c59f84d51bfb594e9ac86d496c708 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 29 Mar 2021 23:15:31 +0100 Subject: [PATCH] Fix shifting limits and LLVM code gen bug relating to shifts --- src/ir.cpp | 13 +++++++------ src/llvm_backend.cpp | 14 ++++++++------ src/llvm_backend_opt.cpp | 3 ++- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/ir.cpp b/src/ir.cpp index 96595c38d..090967ad8 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -4639,13 +4639,13 @@ handle_op: irValue *bits = right; - irValue *max = ir_value_constant(type, exact_value_i64(8*type_size_of(type))); - irValue *less_equal_width = ir_emit(proc, ir_instr_binary_op(proc, Token_Lt, bits, max, t_llvm_bool)); + irValue *bit_size = ir_value_constant(type, exact_value_i64(8*type_size_of(type))); + irValue *width_test = ir_emit(proc, ir_instr_binary_op(proc, Token_Lt, bits, bit_size, t_llvm_bool)); irValue *zero = ir_value_constant(type, exact_value_i64(0)); irValue *res = ir_emit(proc, ir_instr_binary_op(proc, op, left, bits, type)); - return ir_emit_select(proc, less_equal_width, res, zero); + return ir_emit_select(proc, width_test, res, zero); } case Token_Shr: { @@ -4655,10 +4655,11 @@ handle_op: irValue *bits = right; - irValue *max = ir_value_constant(type, exact_value_i64(8*type_size_of(type))); - irValue *less_equal_width = ir_emit(proc, ir_instr_binary_op(proc, Token_Lt, bits, max, t_llvm_bool)); + irValue *bit_size = ir_value_constant(type, exact_value_i64(8*type_size_of(type))); + irValue *max = ir_value_constant(type, exact_value_i64(8*type_size_of(type)-1)); + irValue *width_test = ir_emit(proc, ir_instr_binary_op(proc, Token_Lt, bits, bit_size, t_llvm_bool)); - bits = ir_emit_select(proc, less_equal_width, bits, max); + bits = ir_emit_select(proc, width_test, bits, max); return ir_emit(proc, ir_instr_binary_op(proc, op, left, bits, type)); } 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 { diff --git a/src/llvm_backend_opt.cpp b/src/llvm_backend_opt.cpp index d8b1f8e75..cc2610ec5 100644 --- a/src/llvm_backend_opt.cpp +++ b/src/llvm_backend_opt.cpp @@ -8,8 +8,9 @@ void lb_populate_function_pass_manager(LLVMPassManagerRef fpm, bool ignore_memcp } LLVMAddPromoteMemoryToRegisterPass(fpm); LLVMAddMergedLoadStoreMotionPass(fpm); + LLVMAddConstantPropagationPass(fpm); LLVMAddEarlyCSEPass(fpm); - // LLVMAddEarlyCSEMemSSAPass(fpm); + LLVMAddConstantPropagationPass(fpm); LLVMAddMergedLoadStoreMotionPass(fpm); LLVMAddPromoteMemoryToRegisterPass(fpm);