Fix case where occasionally atomic_load would miscompile.

This commit is contained in:
Christoffer Lerno
2025-03-05 01:58:07 +01:00
parent 28b1e4d182
commit cf0405930e
6 changed files with 13 additions and 9 deletions

View File

@@ -182,8 +182,7 @@ fn void update_game()
}
// Collision logic: ball vs player
if (rl::checkCollisionCircleRec(ball.position, ball.radius,
Rectangle{ player.position.x - player.size.x / 2, player.position.y - player.size.y / 2, player.size.x, player.size.y}))
if (rl::checkCollisionCircleRec(ball.position, ball.radius, { player.position.x - player.size.x / 2, player.position.y - player.size.y / 2, player.size.x, player.size.y}))
{
if (ball.speed.y > 0)
{

View File

@@ -108,7 +108,7 @@ INLINE void llvm_emit_compare_exchange(GenContext *c, BEValue *result_value, Exp
ordering_to_llvm(success_ordering), ordering_to_llvm(failure_ordering), false);
if (alignment && alignment >= type_abi_alignment(type))
{
ASSERT(is_power_of_two(alignment));
ASSERT_SPAN(expr, is_power_of_two(alignment));
LLVMSetAlignment(result, alignment);
}
if (is_volatile) LLVMSetVolatile(result, true);
@@ -235,10 +235,12 @@ INLINE void llvm_emit_atomic_fetch(GenContext *c, BuiltinFunction func, BEValue
INLINE void llvm_emit_atomic_load(GenContext *c, BEValue *result_value, Expr *expr)
{
llvm_emit_expr(c, result_value, expr->call_expr.arguments[0]);
llvm_value_deref(c, result_value);
llvm_value_rvalue(c, result_value);
if (expr->call_expr.arguments[1]->const_expr.b) LLVMSetVolatile(result_value->value, true);
LLVMSetOrdering(result_value->value, llvm_atomic_ordering(expr->call_expr.arguments[2]->const_expr.ixx.i.low));
Type *type = result_value->type->pointer;
LLVMValueRef val = llvm_load(c, llvm_get_type(c, type), result_value->value, type_abi_alignment(type), "");
if (expr->call_expr.arguments[1]->const_expr.b) LLVMSetVolatile(val, true);
LLVMSetOrdering(val, llvm_atomic_ordering(expr->call_expr.arguments[2]->const_expr.ixx.i.low));
llvm_value_set(result_value, val, type);
}
INLINE void llvm_emit_unaligned_load(GenContext *c, BEValue *result_value, Expr *expr)

View File

@@ -3064,6 +3064,8 @@ void llvm_emit_int_comp_raw(GenContext *c, BEValue *result, Type *lhs_type, Type
}
}
}
ASSERT(LLVMTypeOf(lhs_value) == LLVMTypeOf(rhs_value));
if (lhs_signed && !rhs_signed && !vector_type && llvm_is_const(lhs_value) && type_size(lhs_type) <= 8)
{
long long val = LLVMConstIntGetSExtValue(lhs_value);

View File

@@ -458,7 +458,7 @@ INLINE LLVMValueRef llvm_store_decl_raw(GenContext *context, Decl *decl, LLVMVal
INLINE LLVMValueRef llvm_store_to_ptr(GenContext *c, LLVMValueRef destination, BEValue *value);
INLINE LLVMValueRef llvm_store_to_ptr_raw(GenContext *c, LLVMValueRef pointer, LLVMValueRef value, Type *type);
LLVMValueRef llvm_store_to_ptr_aligned(GenContext *c, LLVMValueRef destination, BEValue *value, AlignSize alignment);
LLVMValueRef llvm_store_to_ptr_raw_aligned(GenContext *context, LLVMValueRef pointer, LLVMValueRef value, AlignSize alignment);
LLVMValueRef llvm_store_to_ptr_raw_aligned(GenContext *c, LLVMValueRef pointer, LLVMValueRef value, AlignSize alignment);
void llvm_store_to_ptr_zero(GenContext *context, LLVMValueRef pointer, Type *type);
TypeSize llvm_store_size(GenContext *c, LLVMTypeRef type);
TypeSize llvm_alloc_size(GenContext *c, LLVMTypeRef type);

View File

@@ -4,10 +4,11 @@
#include "llvm_codegen_internal.h"
LLVMValueRef llvm_store_to_ptr_raw_aligned(GenContext *context, LLVMValueRef pointer, LLVMValueRef value, AlignSize alignment)
LLVMValueRef llvm_store_to_ptr_raw_aligned(GenContext *c, LLVMValueRef pointer, LLVMValueRef value, AlignSize alignment)
{
ASSERT(alignment > 0);
LLVMValueRef ref = LLVMBuildStore(context->builder, value, pointer);
assert(LLVMTypeOf(value) != c->bool_type);
LLVMValueRef ref = LLVMBuildStore(c->builder, value, pointer);
llvm_set_alignment(ref, alignment);
return ref;
}