@@ -265,7 +265,7 @@ pub trait FnTypeExt<'a, 'tcx> {
265
265
fn llvm_type ( & self , cx : & CodegenCx < ' a , ' tcx > ) -> Type ;
266
266
fn llvm_cconv ( & self ) -> llvm:: CallConv ;
267
267
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 ) ;
269
269
}
270
270
271
271
impl < ' 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>> {
640
640
}
641
641
}
642
642
643
- fn apply_attrs_callsite ( & self , callsite : ValueRef ) {
643
+ fn apply_attrs_callsite ( & self , bx : & Builder < ' a , ' tcx > , callsite : ValueRef ) {
644
644
let mut i = 0 ;
645
645
let mut apply = |attrs : & ArgAttributes | {
646
646
attrs. apply_callsite ( llvm:: AttributePlace :: Argument ( i) , callsite) ;
@@ -653,6 +653,24 @@ impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> {
653
653
PassMode :: Indirect ( ref attrs) => apply ( attrs) ,
654
654
_ => { }
655
655
}
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
+ }
656
674
for arg in & self . args {
657
675
if arg. pad . is_some ( ) {
658
676
apply ( & ArgAttributes :: new ( ) ) ;
0 commit comments