@@ -430,9 +430,32 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
430430 i += 1 ;
431431 i - 1
432432 } ;
433+
434+ let apply_range_attr = |idx : AttributePlace , scalar : rustc_target:: abi:: Scalar | {
435+ if cx. sess ( ) . opts . optimize != config:: OptLevel :: No
436+ && llvm_util:: get_version ( ) >= ( 19 , 0 , 0 )
437+ && matches ! ( scalar. primitive( ) , Int ( ..) )
438+ // If the value is a boolean, the range is 0..2 and that ultimately
439+ // become 0..0 when the type becomes i1, which would be rejected
440+ // by the LLVM verifier.
441+ && !scalar. is_bool ( )
442+ // LLVM also rejects full range.
443+ && !scalar. is_always_valid ( cx)
444+ {
445+ attributes:: apply_to_llfn (
446+ llfn,
447+ idx,
448+ & [ llvm:: CreateRangeAttr ( cx. llcx , scalar. size ( cx) , scalar. valid_range ( cx) ) ] ,
449+ ) ;
450+ }
451+ } ;
452+
433453 match & self . ret . mode {
434454 PassMode :: Direct ( attrs) => {
435455 attrs. apply_attrs_to_llfn ( llvm:: AttributePlace :: ReturnValue , cx, llfn) ;
456+ if let abi:: Abi :: Scalar ( scalar) = self . ret . layout . abi {
457+ apply_range_attr ( llvm:: AttributePlace :: ReturnValue , scalar) ;
458+ }
436459 }
437460 PassMode :: Indirect { attrs, meta_attrs : _, on_stack } => {
438461 assert ! ( !on_stack) ;
@@ -471,8 +494,13 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
471494 ) ;
472495 attributes:: apply_to_llfn ( llfn, llvm:: AttributePlace :: Argument ( i) , & [ byval] ) ;
473496 }
474- PassMode :: Direct ( attrs)
475- | PassMode :: Indirect { attrs, meta_attrs : None , on_stack : false } => {
497+ PassMode :: Direct ( attrs) => {
498+ let i = apply ( attrs) ;
499+ if let abi:: Abi :: Scalar ( scalar) = arg. layout . abi {
500+ apply_range_attr ( llvm:: AttributePlace :: Argument ( i) , scalar) ;
501+ }
502+ }
503+ PassMode :: Indirect { attrs, meta_attrs : None , on_stack : false } => {
476504 apply ( attrs) ;
477505 }
478506 PassMode :: Indirect { attrs, meta_attrs : Some ( meta_attrs) , on_stack } => {
@@ -481,8 +509,12 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
481509 apply ( meta_attrs) ;
482510 }
483511 PassMode :: Pair ( a, b) => {
484- apply ( a) ;
485- apply ( b) ;
512+ let i = apply ( a) ;
513+ let ii = apply ( b) ;
514+ if let abi:: Abi :: ScalarPair ( scalar_a, scalar_b) = arg. layout . abi {
515+ apply_range_attr ( llvm:: AttributePlace :: Argument ( i) , scalar_a) ;
516+ apply_range_attr ( llvm:: AttributePlace :: Argument ( ii) , scalar_b) ;
517+ }
486518 }
487519 PassMode :: Cast { cast, pad_i32 } => {
488520 if * pad_i32 {
@@ -537,15 +569,18 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
537569 }
538570 _ => { }
539571 }
540- if let abi:: Abi :: Scalar ( scalar) = self . ret . layout . abi {
541- // If the value is a boolean, the range is 0..2 and that ultimately
542- // become 0..0 when the type becomes i1, which would be rejected
543- // by the LLVM verifier.
544- if let Int ( ..) = scalar. primitive ( ) {
545- if !scalar. is_bool ( ) && !scalar. is_always_valid ( bx) {
546- bx. range_metadata ( callsite, scalar. valid_range ( bx) ) ;
547- }
548- }
572+ if bx. cx . sess ( ) . opts . optimize != config:: OptLevel :: No
573+ && llvm_util:: get_version ( ) < ( 19 , 0 , 0 )
574+ && let abi:: Abi :: Scalar ( scalar) = self . ret . layout . abi
575+ && matches ! ( scalar. primitive( ) , Int ( ..) )
576+ // If the value is a boolean, the range is 0..2 and that ultimately
577+ // become 0..0 when the type becomes i1, which would be rejected
578+ // by the LLVM verifier.
579+ && !scalar. is_bool ( )
580+ // LLVM also rejects full range.
581+ && !scalar. is_always_valid ( bx)
582+ {
583+ bx. range_metadata ( callsite, scalar. valid_range ( bx) ) ;
549584 }
550585 for arg in self . args . iter ( ) {
551586 match & arg. mode {
0 commit comments