@@ -1284,7 +1284,50 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
1284
1284
}
1285
1285
1286
1286
fn fcmp ( & mut self , op : RealPredicate , lhs : RValue < ' gcc > , rhs : RValue < ' gcc > ) -> RValue < ' gcc > {
1287
- self . context . new_comparison ( self . location , op. to_gcc_comparison ( ) , lhs, rhs)
1287
+ // LLVM has a concept of "unordered compares", where eg ULT returns true if either the two
1288
+ // arguments are unordered (i.e. either is NaN), or the lhs is less than the rhs. GCC does
1289
+ // not natively have this concept, so in some cases we must manually handle NaNs
1290
+ let must_handle_nan = match op {
1291
+ RealPredicate :: RealPredicateFalse => unreachable ! ( ) ,
1292
+ RealPredicate :: RealOEQ => false ,
1293
+ RealPredicate :: RealOGT => false ,
1294
+ RealPredicate :: RealOGE => false ,
1295
+ RealPredicate :: RealOLT => false ,
1296
+ RealPredicate :: RealOLE => false ,
1297
+ RealPredicate :: RealONE => false ,
1298
+ RealPredicate :: RealORD => unreachable ! ( ) ,
1299
+ RealPredicate :: RealUNO => unreachable ! ( ) ,
1300
+ RealPredicate :: RealUEQ => false ,
1301
+ RealPredicate :: RealUGT => true ,
1302
+ RealPredicate :: RealUGE => true ,
1303
+ RealPredicate :: RealULT => true ,
1304
+ RealPredicate :: RealULE => true ,
1305
+ RealPredicate :: RealUNE => false ,
1306
+ RealPredicate :: RealPredicateTrue => unreachable ! ( ) ,
1307
+ } ;
1308
+
1309
+ let cmp = self . context . new_comparison ( self . location , op. to_gcc_comparison ( ) , lhs, rhs) ;
1310
+
1311
+ if must_handle_nan {
1312
+ let is_nan = self . context . new_binary_op (
1313
+ self . location ,
1314
+ BinaryOp :: LogicalOr ,
1315
+ self . cx . bool_type ,
1316
+ // compare a value to itself to check whether it is NaN
1317
+ self . context . new_comparison ( self . location , ComparisonOp :: NotEquals , lhs, lhs) ,
1318
+ self . context . new_comparison ( self . location , ComparisonOp :: NotEquals , rhs, rhs) ,
1319
+ ) ;
1320
+
1321
+ self . context . new_binary_op (
1322
+ self . location ,
1323
+ BinaryOp :: LogicalOr ,
1324
+ self . cx . bool_type ,
1325
+ is_nan,
1326
+ cmp,
1327
+ )
1328
+ } else {
1329
+ cmp
1330
+ }
1288
1331
}
1289
1332
1290
1333
/* Miscellaneous instructions */
0 commit comments