Skip to content

Commit 685c6e9

Browse files
committed
rename min/maxnum intrinsics to min/maximum_number and fix their LLVM lowering
1 parent d3877ec commit 685c6e9

15 files changed

Lines changed: 166 additions & 85 deletions

File tree

compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,74 +1267,90 @@ fn codegen_regular_intrinsic_call<'tcx>(
12671267
ret.write_cvalue(fx, val);
12681268
}
12691269

1270-
sym::minnumf16 => {
1270+
sym::minimum_numberf16 => {
12711271
intrinsic_args!(fx, args => (a, b); intrinsic);
12721272
let a = a.load_scalar(fx);
12731273
let b = b.load_scalar(fx);
12741274

1275+
// FIXME: make sure this has the intended behavior for SNaN
1276+
// (returning the other argument).
12751277
let val = crate::num::codegen_float_min(fx, a, b);
12761278
let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f16));
12771279
ret.write_cvalue(fx, val);
12781280
}
1279-
sym::minnumf32 => {
1281+
sym::minimum_numberf32 => {
12801282
intrinsic_args!(fx, args => (a, b); intrinsic);
12811283
let a = a.load_scalar(fx);
12821284
let b = b.load_scalar(fx);
12831285

1286+
// FIXME: make sure this has the intended behavior for SNaN
1287+
// (returning the other argument).
12841288
let val = crate::num::codegen_float_min(fx, a, b);
12851289
let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f32));
12861290
ret.write_cvalue(fx, val);
12871291
}
1288-
sym::minnumf64 => {
1292+
sym::minimum_numberf64 => {
12891293
intrinsic_args!(fx, args => (a, b); intrinsic);
12901294
let a = a.load_scalar(fx);
12911295
let b = b.load_scalar(fx);
12921296

1297+
// FIXME: make sure this has the intended behavior for SNaN
1298+
// (returning the other argument).
12931299
let val = crate::num::codegen_float_min(fx, a, b);
12941300
let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f64));
12951301
ret.write_cvalue(fx, val);
12961302
}
1297-
sym::minnumf128 => {
1303+
sym::minimum_numberf128 => {
12981304
intrinsic_args!(fx, args => (a, b); intrinsic);
12991305
let a = a.load_scalar(fx);
13001306
let b = b.load_scalar(fx);
13011307

1308+
// FIXME: make sure this has the intended behavior for SNaN
1309+
// (returning the other argument).
13021310
let val = crate::num::codegen_float_min(fx, a, b);
13031311
let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f128));
13041312
ret.write_cvalue(fx, val);
13051313
}
1306-
sym::maxnumf16 => {
1314+
sym::maximum_numberf16 => {
13071315
intrinsic_args!(fx, args => (a, b); intrinsic);
13081316
let a = a.load_scalar(fx);
13091317
let b = b.load_scalar(fx);
13101318

1319+
// FIXME: make sure this has the intended behavior for SNaN
1320+
// (returning the other argument).
13111321
let val = crate::num::codegen_float_max(fx, a, b);
13121322
let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f16));
13131323
ret.write_cvalue(fx, val);
13141324
}
1315-
sym::maxnumf32 => {
1325+
sym::maximum_numberf32 => {
13161326
intrinsic_args!(fx, args => (a, b); intrinsic);
13171327
let a = a.load_scalar(fx);
13181328
let b = b.load_scalar(fx);
13191329

1330+
// FIXME: make sure this has the intended behavior for SNaN
1331+
// (returning the other argument).
13201332
let val = crate::num::codegen_float_max(fx, a, b);
13211333
let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f32));
13221334
ret.write_cvalue(fx, val);
13231335
}
1324-
sym::maxnumf64 => {
1336+
sym::maximum_numberf64 => {
13251337
intrinsic_args!(fx, args => (a, b); intrinsic);
13261338
let a = a.load_scalar(fx);
13271339
let b = b.load_scalar(fx);
13281340

1341+
// FIXME: make sure this has the intended behavior for SNaN
1342+
// (returning the other argument).
13291343
let val = crate::num::codegen_float_max(fx, a, b);
13301344
let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f64));
13311345
ret.write_cvalue(fx, val);
13321346
}
1333-
sym::maxnumf128 => {
1347+
sym::maximum_numberf128 => {
13341348
intrinsic_args!(fx, args => (a, b); intrinsic);
13351349
let a = a.load_scalar(fx);
13361350
let b = b.load_scalar(fx);
13371351

1352+
// FIXME: make sure this has the intended behavior for SNaN
1353+
// (returning the other argument).
13381354
let val = crate::num::codegen_float_max(fx, a, b);
13391355
let val = CValue::by_val(val, fx.layout_of(fx.tcx.types.f128));
13401356
ret.write_cvalue(fx, val);

compiler/rustc_codegen_gcc/src/intrinsic/mod.rs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,10 @@ fn get_simple_intrinsic<'gcc, 'tcx>(
7272
sym::fmuladdf64 => "fma", // TODO: use gcc intrinsic analogous to llvm.fmuladd.f64
7373
sym::fabsf32 => "fabsf",
7474
sym::fabsf64 => "fabs",
75-
sym::minnumf32 => "fminf",
76-
sym::minnumf64 => "fmin",
75+
// FIXME: this does not guarantee the intended behavior for SNaN
76+
// (returning the other argument).
77+
sym::minimum_numberf32 => "fminf",
78+
sym::minimum_numberf64 => "fmin",
7779
sym::minimumf32 => "fminimumf",
7880
sym::minimumf64 => "fminimum",
7981
sym::minimumf128 => {
@@ -92,8 +94,10 @@ fn get_simple_intrinsic<'gcc, 'tcx>(
9294
false,
9395
));
9496
}
95-
sym::maxnumf32 => "fmaxf",
96-
sym::maxnumf64 => "fmax",
97+
// FIXME: this does not guarantee the intended behavior for SNaN
98+
// (returning the other argument).
99+
sym::maximum_numberf32 => "fmaxf",
100+
sym::maximum_numberf64 => "fmax",
97101
sym::maximumf32 => "fmaximumf",
98102
sym::maximumf64 => "fmaximum",
99103
sym::maximumf128 => {
@@ -236,8 +240,10 @@ fn get_simple_function_f128_2args<'gcc, 'tcx>(
236240

237241
let f128_type = cx.type_f128();
238242
let func_name = match name {
239-
sym::maxnumf128 => "fmaxf128",
240-
sym::minnumf128 => "fminf128",
243+
// FIXME: this does not guarantee the intended behavior for SNaN
244+
// (returning the other argument).
245+
sym::maximum_numberf128 => "fmaxf128",
246+
sym::minimum_numberf128 => "fminf128",
241247
sym::copysignf128 => "copysignf128",
242248
_ => return None,
243249
};
@@ -266,8 +272,10 @@ fn f16_builtin<'gcc, 'tcx>(
266272
sym::fabsf16 => "fabsf",
267273
sym::floorf16 => "__builtin_floorf",
268274
sym::fmaf16 => "fmaf",
269-
sym::maxnumf16 => "__builtin_fmaxf",
270-
sym::minnumf16 => "__builtin_fminf",
275+
// FIXME: this does not guarantee the intended behavior for SNaN
276+
// (returning the other argument).
277+
sym::maximum_numberf16 => "__builtin_fmaxf",
278+
sym::minimum_numberf16 => "__builtin_fminf",
271279
sym::powf16 => "__builtin_powf",
272280
sym::powif16 => {
273281
let func = cx.context.get_builtin_function("__builtin_powif");
@@ -333,8 +341,8 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
333341
| sym::fabsf16
334342
| sym::floorf16
335343
| sym::fmaf16
336-
| sym::maxnumf16
337-
| sym::minnumf16
344+
| sym::maximum_numberf16
345+
| sym::minimum_numberf16
338346
| sym::powf16
339347
| sym::powif16
340348
| sym::roundf16

compiler/rustc_codegen_llvm/src/intrinsic.rs

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -113,23 +113,13 @@ fn call_simple_intrinsic<'ll, 'tcx>(
113113
sym::fabsf64 => ("llvm.fabs", &[bx.type_f64()]),
114114
sym::fabsf128 => ("llvm.fabs", &[bx.type_f128()]),
115115

116-
sym::minnumf16 => ("llvm.minnum", &[bx.type_f16()]),
117-
sym::minnumf32 => ("llvm.minnum", &[bx.type_f32()]),
118-
sym::minnumf64 => ("llvm.minnum", &[bx.type_f64()]),
119-
sym::minnumf128 => ("llvm.minnum", &[bx.type_f128()]),
120-
121116
// FIXME: LLVM currently mis-compile those intrinsics, re-enable them
122117
// when llvm/llvm-project#{139380,139381,140445} are fixed.
123118
//sym::minimumf16 => ("llvm.minimum", &[bx.type_f16()]),
124119
//sym::minimumf32 => ("llvm.minimum", &[bx.type_f32()]),
125120
//sym::minimumf64 => ("llvm.minimum", &[bx.type_f64()]),
126121
//sym::minimumf128 => ("llvm.minimum", &[cx.type_f128()]),
127122
//
128-
sym::maxnumf16 => ("llvm.maxnum", &[bx.type_f16()]),
129-
sym::maxnumf32 => ("llvm.maxnum", &[bx.type_f32()]),
130-
sym::maxnumf64 => ("llvm.maxnum", &[bx.type_f64()]),
131-
sym::maxnumf128 => ("llvm.maxnum", &[bx.type_f128()]),
132-
133123
// FIXME: LLVM currently mis-compile those intrinsics, re-enable them
134124
// when llvm/llvm-project#{139380,139381,140445} are fixed.
135125
//sym::maximumf16 => ("llvm.maximum", &[bx.type_f16()]),
@@ -196,6 +186,29 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
196186
let simple = call_simple_intrinsic(self, name, args);
197187
let llval = match name {
198188
_ if simple.is_some() => simple.unwrap(),
189+
sym::minimum_numberf16
190+
| sym::minimum_numberf32
191+
| sym::minimum_numberf64
192+
| sym::minimum_numberf128
193+
| sym::maximum_numberf16
194+
| sym::maximum_numberf32
195+
| sym::maximum_numberf64
196+
| sym::maximum_numberf128 => {
197+
let intrinsic_name = if name.as_str().starts_with("min") {
198+
"llvm.minimumnum"
199+
} else {
200+
"llvm.maximumnum"
201+
};
202+
let call = self.call_intrinsic(
203+
intrinsic_name,
204+
&[args[0].layout.immediate_llvm_type(self.cx)],
205+
&[args[0].immediate(), args[1].immediate()],
206+
);
207+
// `nsz` in minimumnum/maximumnum is special: its only effect is to make signed-zero
208+
// ordering non-deterministic.
209+
unsafe { llvm::LLVMRustSetNoSignedZeros(call) };
210+
call
211+
}
199212
sym::ptr_mask => {
200213
let ptr = args[0].immediate();
201214
self.call_intrinsic(

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2045,6 +2045,7 @@ unsafe extern "C" {
20452045
pub(crate) fn LLVMRustSetFastMath(Instr: &Value);
20462046
pub(crate) fn LLVMRustSetAlgebraicMath(Instr: &Value);
20472047
pub(crate) fn LLVMRustSetAllowReassoc(Instr: &Value);
2048+
pub(crate) fn LLVMRustSetNoSignedZeros(Instr: &Value);
20482049

20492050
// Miscellaneous instructions
20502051
pub(crate) fn LLVMRustBuildMemCpy<'a>(

compiler/rustc_const_eval/src/interpret/intrinsics.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,17 @@ pub(crate) enum MinMax {
4040
/// In particular, `-0.0` is considered smaller than `+0.0` and
4141
/// if either input is NaN, the result is NaN.
4242
Minimum,
43-
/// The IEEE-2008 `minNum` operation with the SNaN handling of the
44-
/// IEEE-2019 `minimumNumber` operation - see `f32::min` etc.
43+
/// The IEEE-2019 `minimumNumber` operation but with non-deterministic signed zero handling
44+
/// (like in IEEE-2008 `minNum`) - see `f32::min` etc.
4545
/// In particular, if the inputs are `-0.0` and `+0.0`, the result is non-deterministic,
4646
/// and if one argument is NaN (quiet or signaling), the other one is returned.
4747
MinimumNumber,
4848
/// The IEEE-2019 `maximum` operation - see `f32::maximum` etc.
4949
/// In particular, `-0.0` is considered smaller than `+0.0` and
5050
/// if either input is NaN, the result is NaN.
5151
Maximum,
52-
/// The IEEE-2008 `maxNum` operation with the SNaN handling of the
53-
/// IEEE-2019 `maximumNumber` operation - see `f32::max` etc.
52+
/// The IEEE-2019 `maximumNumber` operation but with non-deterministic signed zero handling
53+
/// (like in IEEE-2008 `maxNum`) - see `f32::max` etc.
5454
/// In particular, if the inputs are `-0.0` and `+0.0`, the result is non-deterministic,
5555
/// and if one argument is NaN (quiet or signaling), the other one is returned.
5656
MaximumNumber,
@@ -542,16 +542,16 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
542542
self.write_scalar(Scalar::from_target_usize(align.bytes(), self), dest)?;
543543
}
544544

545-
sym::minnumf16 => {
545+
sym::minimum_numberf16 => {
546546
self.float_minmax_intrinsic::<Half>(args, MinMax::MinimumNumber, dest)?
547547
}
548-
sym::minnumf32 => {
548+
sym::minimum_numberf32 => {
549549
self.float_minmax_intrinsic::<Single>(args, MinMax::MinimumNumber, dest)?
550550
}
551-
sym::minnumf64 => {
551+
sym::minimum_numberf64 => {
552552
self.float_minmax_intrinsic::<Double>(args, MinMax::MinimumNumber, dest)?
553553
}
554-
sym::minnumf128 => {
554+
sym::minimum_numberf128 => {
555555
self.float_minmax_intrinsic::<Quad>(args, MinMax::MinimumNumber, dest)?
556556
}
557557

@@ -564,16 +564,16 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
564564
}
565565
sym::minimumf128 => self.float_minmax_intrinsic::<Quad>(args, MinMax::Minimum, dest)?,
566566

567-
sym::maxnumf16 => {
567+
sym::maximum_numberf16 => {
568568
self.float_minmax_intrinsic::<Half>(args, MinMax::MaximumNumber, dest)?
569569
}
570-
sym::maxnumf32 => {
570+
sym::maximum_numberf32 => {
571571
self.float_minmax_intrinsic::<Single>(args, MinMax::MaximumNumber, dest)?
572572
}
573-
sym::maxnumf64 => {
573+
sym::maximum_numberf64 => {
574574
self.float_minmax_intrinsic::<Double>(args, MinMax::MaximumNumber, dest)?
575575
}
576-
sym::maxnumf128 => {
576+
sym::maximum_numberf128 => {
577577
self.float_minmax_intrinsic::<Quad>(args, MinMax::MaximumNumber, dest)?
578578
}
579579

compiler/rustc_hir_analysis/src/check/intrinsic.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -147,22 +147,22 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi
147147
| sym::logf32
148148
| sym::logf64
149149
| sym::logf128
150+
| sym::maximum_numberf16
151+
| sym::maximum_numberf32
152+
| sym::maximum_numberf64
153+
| sym::maximum_numberf128
150154
| sym::maximumf16
151155
| sym::maximumf32
152156
| sym::maximumf64
153157
| sym::maximumf128
154-
| sym::maxnumf16
155-
| sym::maxnumf32
156-
| sym::maxnumf64
157-
| sym::maxnumf128
158+
| sym::minimum_numberf16
159+
| sym::minimum_numberf32
160+
| sym::minimum_numberf64
161+
| sym::minimum_numberf128
158162
| sym::minimumf16
159163
| sym::minimumf32
160164
| sym::minimumf64
161165
| sym::minimumf128
162-
| sym::minnumf16
163-
| sym::minnumf32
164-
| sym::minnumf64
165-
| sym::minnumf128
166166
| sym::mul_with_overflow
167167
| sym::needs_drop
168168
| sym::offload
@@ -468,20 +468,20 @@ pub(crate) fn check_intrinsic_type(
468468
sym::fabsf64 => (0, 0, vec![tcx.types.f64], tcx.types.f64),
469469
sym::fabsf128 => (0, 0, vec![tcx.types.f128], tcx.types.f128),
470470

471-
sym::minnumf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16),
472-
sym::minnumf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
473-
sym::minnumf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
474-
sym::minnumf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128),
471+
sym::minimum_numberf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16),
472+
sym::minimum_numberf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
473+
sym::minimum_numberf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
474+
sym::minimum_numberf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128),
475475

476476
sym::minimumf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16),
477477
sym::minimumf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
478478
sym::minimumf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
479479
sym::minimumf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128),
480480

481-
sym::maxnumf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16),
482-
sym::maxnumf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
483-
sym::maxnumf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
484-
sym::maxnumf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128),
481+
sym::maximum_numberf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16),
482+
sym::maximum_numberf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),
483+
sym::maximum_numberf64 => (0, 0, vec![tcx.types.f64, tcx.types.f64], tcx.types.f64),
484+
sym::maximum_numberf128 => (0, 0, vec![tcx.types.f128, tcx.types.f128], tcx.types.f128),
485485

486486
sym::maximumf16 => (0, 0, vec![tcx.types.f16, tcx.types.f16], tcx.types.f16),
487487
sym::maximumf32 => (0, 0, vec![tcx.types.f32, tcx.types.f32], tcx.types.f32),

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,13 @@ extern "C" void LLVMRustSetAllowReassoc(LLVMValueRef V) {
722722
}
723723
}
724724

725+
// Enable the NSZ flag on the given instruction.
726+
extern "C" void LLVMRustSetNoSignedZeros(LLVMValueRef V) {
727+
if (auto I = dyn_cast<Instruction>(unwrap<Value>(V))) {
728+
I->setHasNoSignedZeros(true);
729+
}
730+
}
731+
725732
extern "C" uint64_t LLVMRustGetArrayNumElements(LLVMTypeRef Ty) {
726733
return unwrap(Ty)->getArrayNumElements();
727734
}

compiler/rustc_span/src/symbol.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1206,14 +1206,14 @@ symbols! {
12061206
masked,
12071207
match_beginning_vert,
12081208
match_default_bindings,
1209+
maximum_numberf16,
1210+
maximum_numberf32,
1211+
maximum_numberf64,
1212+
maximum_numberf128,
12091213
maximumf16,
12101214
maximumf32,
12111215
maximumf64,
12121216
maximumf128,
1213-
maxnumf16,
1214-
maxnumf32,
1215-
maxnumf64,
1216-
maxnumf128,
12171217
may_dangle,
12181218
may_unwind,
12191219
maybe_uninit,
@@ -1243,14 +1243,14 @@ symbols! {
12431243
min_generic_const_args,
12441244
min_specialization,
12451245
min_type_alias_impl_trait,
1246+
minimum_numberf16,
1247+
minimum_numberf32,
1248+
minimum_numberf64,
1249+
minimum_numberf128,
12461250
minimumf16,
12471251
minimumf32,
12481252
minimumf64,
12491253
minimumf128,
1250-
minnumf16,
1251-
minnumf32,
1252-
minnumf64,
1253-
minnumf128,
12541254
mips,
12551255
mips32r6,
12561256
mips64,

0 commit comments

Comments
 (0)