Merge commit 'db1a31c243a649e1fe20f5466ba181da5be35c14' into subtree-update_cg_gcc_2025-04-18

This commit is contained in:
Guillaume Gomez
2025-04-18 21:19:50 +02:00
52 changed files with 959 additions and 1241 deletions

View File

@@ -368,16 +368,8 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
let previous_arg_count = args.len();
let orig_args = args;
let args = {
let function_address_names = self.function_address_names.borrow();
let original_function_name = function_address_names.get(&func_ptr);
func_ptr = llvm::adjust_function(self.context, &func_name, func_ptr, args);
llvm::adjust_intrinsic_arguments(
self,
gcc_func,
args.into(),
&func_name,
original_function_name,
)
llvm::adjust_intrinsic_arguments(self, gcc_func, args.into(), &func_name)
};
let args_adjusted = args.len() != previous_arg_count;
let args = self.check_ptr_call("call", func_ptr, &args);
@@ -1271,7 +1263,50 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
}
fn fcmp(&mut self, op: RealPredicate, lhs: RValue<'gcc>, rhs: RValue<'gcc>) -> RValue<'gcc> {
self.context.new_comparison(self.location, op.to_gcc_comparison(), lhs, rhs)
// LLVM has a concept of "unordered compares", where eg ULT returns true if either the two
// arguments are unordered (i.e. either is NaN), or the lhs is less than the rhs. GCC does
// not natively have this concept, so in some cases we must manually handle NaNs
let must_handle_nan = match op {
RealPredicate::RealPredicateFalse => unreachable!(),
RealPredicate::RealOEQ => false,
RealPredicate::RealOGT => false,
RealPredicate::RealOGE => false,
RealPredicate::RealOLT => false,
RealPredicate::RealOLE => false,
RealPredicate::RealONE => false,
RealPredicate::RealORD => unreachable!(),
RealPredicate::RealUNO => unreachable!(),
RealPredicate::RealUEQ => false,
RealPredicate::RealUGT => true,
RealPredicate::RealUGE => true,
RealPredicate::RealULT => true,
RealPredicate::RealULE => true,
RealPredicate::RealUNE => false,
RealPredicate::RealPredicateTrue => unreachable!(),
};
let cmp = self.context.new_comparison(self.location, op.to_gcc_comparison(), lhs, rhs);
if must_handle_nan {
let is_nan = self.context.new_binary_op(
self.location,
BinaryOp::LogicalOr,
self.cx.bool_type,
// compare a value to itself to check whether it is NaN
self.context.new_comparison(self.location, ComparisonOp::NotEquals, lhs, lhs),
self.context.new_comparison(self.location, ComparisonOp::NotEquals, rhs, rhs),
);
self.context.new_binary_op(
self.location,
BinaryOp::LogicalOr,
self.cx.bool_type,
is_nan,
cmp,
)
} else {
cmp
}
}
/* Miscellaneous instructions */