@@ -92,6 +92,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
92
92
let invalid_monomorphization_int_type = |ty| {
93
93
bx. tcx ( ) . dcx ( ) . emit_err ( InvalidMonomorphization :: BasicIntegerType { span, name, ty } ) ;
94
94
} ;
95
+ let invalid_monomorphization_int_or_ptr_type = |ty| {
96
+ bx. tcx ( ) . dcx ( ) . emit_err ( InvalidMonomorphization :: BasicIntegerOrPtrType {
97
+ span,
98
+ name,
99
+ ty,
100
+ } ) ;
101
+ } ;
95
102
96
103
let parse_atomic_ordering = |ord : ty:: Value < ' tcx > | {
97
104
let discr = ord. valtree . unwrap_branch ( ) [ 0 ] . unwrap_leaf ( ) ;
@@ -351,7 +358,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
351
358
sym:: atomic_load => {
352
359
let ty = fn_args. type_at ( 0 ) ;
353
360
if !( int_type_width_signed ( ty, bx. tcx ( ) ) . is_some ( ) || ty. is_raw_ptr ( ) ) {
354
- invalid_monomorphization_int_type ( ty) ;
361
+ invalid_monomorphization_int_or_ptr_type ( ty) ;
355
362
return Ok ( ( ) ) ;
356
363
}
357
364
let ordering = fn_args. const_at ( 1 ) . to_value ( ) ;
@@ -367,7 +374,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
367
374
sym:: atomic_store => {
368
375
let ty = fn_args. type_at ( 0 ) ;
369
376
if !( int_type_width_signed ( ty, bx. tcx ( ) ) . is_some ( ) || ty. is_raw_ptr ( ) ) {
370
- invalid_monomorphization_int_type ( ty) ;
377
+ invalid_monomorphization_int_or_ptr_type ( ty) ;
371
378
return Ok ( ( ) ) ;
372
379
}
373
380
let ordering = fn_args. const_at ( 1 ) . to_value ( ) ;
@@ -377,10 +384,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
377
384
bx. atomic_store ( val, ptr, parse_atomic_ordering ( ordering) , size) ;
378
385
return Ok ( ( ) ) ;
379
386
}
387
+ // These are all AtomicRMW ops
380
388
sym:: atomic_cxchg | sym:: atomic_cxchgweak => {
381
389
let ty = fn_args. type_at ( 0 ) ;
382
390
if !( int_type_width_signed ( ty, bx. tcx ( ) ) . is_some ( ) || ty. is_raw_ptr ( ) ) {
383
- invalid_monomorphization_int_type ( ty) ;
391
+ invalid_monomorphization_int_or_ptr_type ( ty) ;
384
392
return Ok ( ( ) ) ;
385
393
}
386
394
let succ_ordering = fn_args. const_at ( 1 ) . to_value ( ) ;
@@ -407,7 +415,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
407
415
408
416
return Ok ( ( ) ) ;
409
417
}
410
- // These are all AtomicRMW ops
411
418
sym:: atomic_max | sym:: atomic_min => {
412
419
let atom_op = if name == sym:: atomic_max {
413
420
AtomicRmwBinOp :: AtomicMax
@@ -420,7 +427,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
420
427
let ordering = fn_args. const_at ( 1 ) . to_value ( ) ;
421
428
let ptr = args[ 0 ] . immediate ( ) ;
422
429
let val = args[ 1 ] . immediate ( ) ;
423
- bx. atomic_rmw ( atom_op, ptr, val, parse_atomic_ordering ( ordering) )
430
+ bx. atomic_rmw (
431
+ atom_op,
432
+ ptr,
433
+ val,
434
+ parse_atomic_ordering ( ordering) ,
435
+ /* ret_ptr */ false ,
436
+ )
424
437
} else {
425
438
invalid_monomorphization_int_type ( ty) ;
426
439
return Ok ( ( ) ) ;
@@ -438,21 +451,44 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
438
451
let ordering = fn_args. const_at ( 1 ) . to_value ( ) ;
439
452
let ptr = args[ 0 ] . immediate ( ) ;
440
453
let val = args[ 1 ] . immediate ( ) ;
441
- bx. atomic_rmw ( atom_op, ptr, val, parse_atomic_ordering ( ordering) )
454
+ bx. atomic_rmw (
455
+ atom_op,
456
+ ptr,
457
+ val,
458
+ parse_atomic_ordering ( ordering) ,
459
+ /* ret_ptr */ false ,
460
+ )
442
461
} else {
443
462
invalid_monomorphization_int_type ( ty) ;
444
463
return Ok ( ( ) ) ;
445
464
}
446
465
}
447
- sym:: atomic_xchg
448
- | sym:: atomic_xadd
466
+ sym:: atomic_xchg => {
467
+ let ty = fn_args. type_at ( 0 ) ;
468
+ let ordering = fn_args. const_at ( fn_args. len ( ) - 1 ) . to_value ( ) ;
469
+ let ptr = args[ 0 ] . immediate ( ) ;
470
+ let val = args[ 1 ] . immediate ( ) ;
471
+ if int_type_width_signed ( ty, bx. tcx ( ) ) . is_some ( ) || ty. is_raw_ptr ( ) {
472
+ let atomic_op = AtomicRmwBinOp :: AtomicXchg ;
473
+ bx. atomic_rmw (
474
+ atomic_op,
475
+ ptr,
476
+ val,
477
+ parse_atomic_ordering ( ordering) ,
478
+ /* ret_ptr */ ty. is_raw_ptr ( ) ,
479
+ )
480
+ } else {
481
+ invalid_monomorphization_int_or_ptr_type ( ty) ;
482
+ return Ok ( ( ) ) ;
483
+ }
484
+ }
485
+ sym:: atomic_xadd
449
486
| sym:: atomic_xsub
450
487
| sym:: atomic_and
451
488
| sym:: atomic_nand
452
489
| sym:: atomic_or
453
490
| sym:: atomic_xor => {
454
491
let atom_op = match name {
455
- sym:: atomic_xchg => AtomicRmwBinOp :: AtomicXchg ,
456
492
sym:: atomic_xadd => AtomicRmwBinOp :: AtomicAdd ,
457
493
sym:: atomic_xsub => AtomicRmwBinOp :: AtomicSub ,
458
494
sym:: atomic_and => AtomicRmwBinOp :: AtomicAnd ,
@@ -462,14 +498,28 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
462
498
_ => unreachable ! ( ) ,
463
499
} ;
464
500
465
- let ty = fn_args. type_at ( 0 ) ;
466
- if int_type_width_signed ( ty, bx. tcx ( ) ) . is_some ( ) || ty. is_raw_ptr ( ) {
467
- let ordering = fn_args. const_at ( 1 ) . to_value ( ) ;
468
- let ptr = args[ 0 ] . immediate ( ) ;
469
- let val = args[ 1 ] . immediate ( ) ;
470
- bx. atomic_rmw ( atom_op, ptr, val, parse_atomic_ordering ( ordering) )
501
+ // The type of the in-memory data.
502
+ let ty_mem = fn_args. type_at ( 0 ) ;
503
+ // The type of the 2nd operand, given by-value.
504
+ let ty_op = fn_args. type_at ( 1 ) ;
505
+
506
+ let ordering = fn_args. const_at ( 2 ) . to_value ( ) ;
507
+ let ptr = args[ 0 ] . immediate ( ) ; // of type "pointer to `ty_mem`"
508
+ let val = args[ 1 ] . immediate ( ) ; // of type `ty_op`
509
+ // We require either both arguments to have the same integer type, or the first to
510
+ // be a pointer and the second to be `usize`.
511
+ if ( int_type_width_signed ( ty_mem, bx. tcx ( ) ) . is_some ( ) && ty_op == ty_mem)
512
+ || ( ty_mem. is_raw_ptr ( ) && ty_op == bx. tcx ( ) . types . usize )
513
+ {
514
+ bx. atomic_rmw (
515
+ atom_op,
516
+ ptr,
517
+ val,
518
+ parse_atomic_ordering ( ordering) ,
519
+ /* ret_ptr */ ty_mem. is_raw_ptr ( ) ,
520
+ )
471
521
} else {
472
- invalid_monomorphization_int_type ( ty ) ;
522
+ invalid_monomorphization_int_or_ptr_type ( ty_mem ) ;
473
523
return Ok ( ( ) ) ;
474
524
}
475
525
}
0 commit comments