@@ -415,9 +415,32 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
415
415
i += 1 ;
416
416
i - 1
417
417
} ;
418
+
419
+ let apply_range_attr = |idx : AttributePlace , scalar : rustc_target:: abi:: Scalar | {
420
+ if cx. sess ( ) . opts . optimize != config:: OptLevel :: No
421
+ && llvm_util:: get_version ( ) >= ( 19 , 0 , 0 )
422
+ && matches ! ( scalar. primitive( ) , Int ( ..) )
423
+ // If the value is a boolean, the range is 0..2 and that ultimately
424
+ // become 0..0 when the type becomes i1, which would be rejected
425
+ // by the LLVM verifier.
426
+ && !scalar. is_bool ( )
427
+ // LLVM also rejects full range.
428
+ && !scalar. is_always_valid ( cx)
429
+ {
430
+ attributes:: apply_to_llfn (
431
+ llfn,
432
+ idx,
433
+ & [ llvm:: CreateRangeAttr ( cx. llcx , scalar. size ( cx) , scalar. valid_range ( cx) ) ] ,
434
+ ) ;
435
+ }
436
+ } ;
437
+
418
438
match & self . ret . mode {
419
439
PassMode :: Direct ( attrs) => {
420
440
attrs. apply_attrs_to_llfn ( llvm:: AttributePlace :: ReturnValue , cx, llfn) ;
441
+ if let abi:: Abi :: Scalar ( scalar) = self . ret . layout . abi {
442
+ apply_range_attr ( llvm:: AttributePlace :: ReturnValue , scalar) ;
443
+ }
421
444
}
422
445
PassMode :: Indirect { attrs, meta_attrs : _, on_stack } => {
423
446
assert ! ( !on_stack) ;
@@ -456,8 +479,13 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
456
479
) ;
457
480
attributes:: apply_to_llfn ( llfn, llvm:: AttributePlace :: Argument ( i) , & [ byval] ) ;
458
481
}
459
- PassMode :: Direct ( attrs)
460
- | PassMode :: Indirect { attrs, meta_attrs : None , on_stack : false } => {
482
+ PassMode :: Direct ( attrs) => {
483
+ let i = apply ( attrs) ;
484
+ if let abi:: Abi :: Scalar ( scalar) = arg. layout . abi {
485
+ apply_range_attr ( llvm:: AttributePlace :: Argument ( i) , scalar) ;
486
+ }
487
+ }
488
+ PassMode :: Indirect { attrs, meta_attrs : None , on_stack : false } => {
461
489
apply ( attrs) ;
462
490
}
463
491
PassMode :: Indirect { attrs, meta_attrs : Some ( meta_attrs) , on_stack } => {
@@ -466,8 +494,12 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
466
494
apply ( meta_attrs) ;
467
495
}
468
496
PassMode :: Pair ( a, b) => {
469
- apply ( a) ;
470
- apply ( b) ;
497
+ let i = apply ( a) ;
498
+ let ii = apply ( b) ;
499
+ if let abi:: Abi :: ScalarPair ( scalar_a, scalar_b) = arg. layout . abi {
500
+ apply_range_attr ( llvm:: AttributePlace :: Argument ( i) , scalar_a) ;
501
+ apply_range_attr ( llvm:: AttributePlace :: Argument ( ii) , scalar_b) ;
502
+ }
471
503
}
472
504
PassMode :: Cast { cast, pad_i32 } => {
473
505
if * pad_i32 {
@@ -517,15 +549,18 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
517
549
}
518
550
_ => { }
519
551
}
520
- if let abi:: Abi :: Scalar ( scalar) = self . ret . layout . abi {
521
- // If the value is a boolean, the range is 0..2 and that ultimately
522
- // become 0..0 when the type becomes i1, which would be rejected
523
- // by the LLVM verifier.
524
- if let Int ( ..) = scalar. primitive ( ) {
525
- if !scalar. is_bool ( ) && !scalar. is_always_valid ( bx) {
526
- bx. range_metadata ( callsite, scalar. valid_range ( bx) ) ;
527
- }
528
- }
552
+ if bx. cx . sess ( ) . opts . optimize != config:: OptLevel :: No
553
+ && llvm_util:: get_version ( ) < ( 19 , 0 , 0 )
554
+ && let abi:: Abi :: Scalar ( scalar) = self . ret . layout . abi
555
+ && matches ! ( scalar. primitive( ) , Int ( ..) )
556
+ // If the value is a boolean, the range is 0..2 and that ultimately
557
+ // become 0..0 when the type becomes i1, which would be rejected
558
+ // by the LLVM verifier.
559
+ && !scalar. is_bool ( )
560
+ // LLVM also rejects full range.
561
+ && !scalar. is_always_valid ( bx)
562
+ {
563
+ bx. range_metadata ( callsite, scalar. valid_range ( bx) ) ;
529
564
}
530
565
for arg in self . args . iter ( ) {
531
566
match & arg. mode {
0 commit comments