@@ -265,7 +265,7 @@ pub trait FnTypeExt<'a, 'tcx> {
265265 fn llvm_type ( & self , cx : & CodegenCx < ' a , ' tcx > ) -> Type ;
266266 fn llvm_cconv ( & self ) -> llvm:: CallConv ;
267267 fn apply_attrs_llfn ( & self , llfn : ValueRef ) ;
268- fn apply_attrs_callsite ( & self , callsite : ValueRef ) ;
268+ fn apply_attrs_callsite ( & self , bx : & Builder < ' a , ' tcx > , callsite : ValueRef ) ;
269269}
270270
271271impl < ' a , ' tcx > FnTypeExt < ' a , ' tcx > for FnType < ' tcx , Ty < ' tcx > > {
@@ -640,7 +640,7 @@ impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> {
640640 }
641641 }
642642
643- fn apply_attrs_callsite ( & self , callsite : ValueRef ) {
643+ fn apply_attrs_callsite ( & self , bx : & Builder < ' a , ' tcx > , callsite : ValueRef ) {
644644 let mut i = 0 ;
645645 let mut apply = |attrs : & ArgAttributes | {
646646 attrs. apply_callsite ( llvm:: AttributePlace :: Argument ( i) , callsite) ;
@@ -653,6 +653,24 @@ impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> {
653653 PassMode :: Indirect ( ref attrs) => apply ( attrs) ,
654654 _ => { }
655655 }
656+ if let layout:: Abi :: Scalar ( ref scalar) = self . ret . layout . abi {
657+ // If the value is a boolean, the range is 0..2 and that ultimately
658+ // become 0..0 when the type becomes i1, which would be rejected
659+ // by the LLVM verifier.
660+ match scalar. value {
661+ layout:: Int ( ..) if !scalar. is_bool ( ) => {
662+ let range = scalar. valid_range_exclusive ( bx. cx ) ;
663+ if range. start != range. end {
664+ // FIXME(nox): This causes very weird type errors about
665+ // SHL operators in constants in stage 2 with LLVM 3.9.
666+ if unsafe { llvm:: LLVMRustVersionMajor ( ) >= 4 } {
667+ bx. range_metadata ( callsite, range) ;
668+ }
669+ }
670+ }
671+ _ => { }
672+ }
673+ }
656674 for arg in & self . args {
657675 if arg. pad . is_some ( ) {
658676 apply ( & ArgAttributes :: new ( ) ) ;
0 commit comments