@@ -415,9 +415,32 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
415415 i += 1 ;
416416 i - 1
417417 } ;
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+
418438 match & self . ret . mode {
419439 PassMode :: Direct ( attrs) => {
420440 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+ }
421444 }
422445 PassMode :: Indirect { attrs, meta_attrs : _, on_stack } => {
423446 assert ! ( !on_stack) ;
@@ -456,8 +479,13 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
456479 ) ;
457480 attributes:: apply_to_llfn ( llfn, llvm:: AttributePlace :: Argument ( i) , & [ byval] ) ;
458481 }
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 } => {
461489 apply ( attrs) ;
462490 }
463491 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>> {
466494 apply ( meta_attrs) ;
467495 }
468496 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+ }
471503 }
472504 PassMode :: Cast { cast, pad_i32 } => {
473505 if * pad_i32 {
@@ -517,15 +549,18 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
517549 }
518550 _ => { }
519551 }
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) ) ;
529564 }
530565 for arg in self . args . iter ( ) {
531566 match & arg. mode {
0 commit comments