Merge commit 'db1a31c243a649e1fe20f5466ba181da5be35c14' into subtree-update_cg_gcc_2025-04-18
This commit is contained in:
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user