1
1
use super :: Builder ;
2
+ use crate :: abi:: ConvSpirvType ;
2
3
use crate :: builder_spirv:: { BuilderCursor , SpirvConst , SpirvValue , SpirvValueExt , SpirvValueKind } ;
3
4
use crate :: spirv_type:: SpirvType ;
4
5
use rspirv:: dr:: { InsertPoint , Instruction , Operand } ;
@@ -313,7 +314,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
313
314
} else {
314
315
for index in 0 ..count {
315
316
let const_index = self . constant_u32 ( self . span ( ) , index as u32 ) ;
316
- let gep_ptr = self . gep ( ptr, & [ const_index] ) ;
317
+ let gep_ptr = self . gep ( pat . ty , ptr, & [ const_index] ) ;
317
318
self . store ( pat, gep_ptr, Align :: from_bytes ( 0 ) . unwrap ( ) ) ;
318
319
}
319
320
}
@@ -339,11 +340,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
339
340
self . store ( zero, index, zero_align) ;
340
341
self . br ( header. llbb ( ) ) ;
341
342
342
- let current_index = header. load ( index, zero_align) ;
343
+ let current_index = header. load ( count . ty , index, zero_align) ;
343
344
let cond = header. icmp ( IntPredicate :: IntULT , current_index, count) ;
344
345
header. cond_br ( cond, body. llbb ( ) , exit. llbb ( ) ) ;
345
346
346
- let gep_ptr = body. gep ( ptr, & [ current_index] ) ;
347
+ let gep_ptr = body. gep ( pat . ty , ptr, & [ current_index] ) ;
347
348
body. store ( pat, gep_ptr, zero_align) ;
348
349
let current_index_plus_1 = body. add ( current_index, one) ;
349
350
body. store ( current_index_plus_1, index, zero_align) ;
@@ -623,14 +624,15 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
623
624
624
625
fn invoke (
625
626
& mut self ,
627
+ llty : Self :: Type ,
626
628
llfn : Self :: Value ,
627
629
args : & [ Self :: Value ] ,
628
630
then : Self :: BasicBlock ,
629
631
_catch : Self :: BasicBlock ,
630
632
funclet : Option < & Self :: Funclet > ,
631
633
) -> Self :: Value {
632
634
// Exceptions don't exist, jump directly to then block
633
- let result = self . call ( llfn, args, funclet) ;
635
+ let result = self . call ( llty , llfn, args, funclet) ;
634
636
self . emit ( ) . branch ( then) . unwrap ( ) ;
635
637
result
636
638
}
@@ -842,12 +844,15 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
842
844
self . fatal ( "array alloca not supported yet" )
843
845
}
844
846
845
- fn load ( & mut self , ptr : Self :: Value , _align : Align ) -> Self :: Value {
847
+ fn load ( & mut self , ty : Self :: Type , ptr : Self :: Value , _align : Align ) -> Self :: Value {
846
848
if let Some ( value) = ptr. const_fold_load ( self ) {
847
849
return value;
848
850
}
849
851
let ty = match self . lookup_type ( ptr. ty ) {
850
- SpirvType :: Pointer { pointee } => pointee,
852
+ SpirvType :: Pointer { pointee } => {
853
+ assert_ty_eq ! ( self , ty, pointee) ;
854
+ pointee
855
+ }
851
856
ty => self . fatal ( & format ! (
852
857
"load called on variable that wasn't a pointer: {:?}" ,
853
858
ty
@@ -859,16 +864,25 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
859
864
. with_type ( ty)
860
865
}
861
866
862
- fn volatile_load ( & mut self , ptr : Self :: Value ) -> Self :: Value {
867
+ fn volatile_load ( & mut self , ty : Self :: Type , ptr : Self :: Value ) -> Self :: Value {
863
868
// TODO: Implement this
864
- let result = self . load ( ptr, Align :: from_bytes ( 0 ) . unwrap ( ) ) ;
869
+ let result = self . load ( ty , ptr, Align :: from_bytes ( 0 ) . unwrap ( ) ) ;
865
870
self . zombie ( result. def ( self ) , "volatile load is not supported yet" ) ;
866
871
result
867
872
}
868
873
869
- fn atomic_load ( & mut self , ptr : Self :: Value , order : AtomicOrdering , _size : Size ) -> Self :: Value {
874
+ fn atomic_load (
875
+ & mut self ,
876
+ ty : Self :: Type ,
877
+ ptr : Self :: Value ,
878
+ order : AtomicOrdering ,
879
+ _size : Size ,
880
+ ) -> Self :: Value {
870
881
let ty = match self . lookup_type ( ptr. ty ) {
871
- SpirvType :: Pointer { pointee } => pointee,
882
+ SpirvType :: Pointer { pointee } => {
883
+ assert_ty_eq ! ( self , ty, pointee) ;
884
+ pointee
885
+ }
872
886
ty => self . fatal ( & format ! (
873
887
"atomic_load called on variable that wasn't a pointer: {:?}" ,
874
888
ty
@@ -903,14 +917,23 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
903
917
let val = if let Some ( llextra) = place. llextra {
904
918
OperandValue :: Ref ( place. llval , Some ( llextra) , place. align )
905
919
} else if self . cx . is_backend_immediate ( place. layout ) {
906
- let llval = self . load ( place. llval , place. align ) ;
920
+ let llval = self . load (
921
+ place. layout . spirv_type ( self . span ( ) , self ) ,
922
+ place. llval ,
923
+ place. align ,
924
+ ) ;
907
925
OperandValue :: Immediate ( self . to_immediate ( llval, place. layout ) )
908
926
} else if let Abi :: ScalarPair ( ref a, ref b) = place. layout . abi {
909
927
let b_offset = a. value . size ( self ) . align_to ( b. value . align ( self ) . abi ) ;
910
928
929
+ let pair_ty = place. layout . spirv_type ( self . span ( ) , self ) ;
911
930
let mut load = |i, scalar : & Scalar , align| {
912
- let llptr = self . struct_gep ( place. llval , i as u64 ) ;
913
- let load = self . load ( llptr, align) ;
931
+ let llptr = self . struct_gep ( pair_ty, place. llval , i as u64 ) ;
932
+ let load = self . load (
933
+ self . scalar_pair_element_backend_type ( place. layout , i, false ) ,
934
+ llptr,
935
+ align,
936
+ ) ;
914
937
// WARN! This does not go through to_immediate due to only having a Scalar, not a Ty, but it still does
915
938
// whatever to_immediate does!
916
939
if scalar. is_bool ( ) {
@@ -943,12 +966,12 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
943
966
let zero = self . const_usize ( 0 ) ;
944
967
let start = dest. project_index ( & mut self , zero) . llval ;
945
968
946
- let align = dest
947
- . align
948
- . restrict_for_offset ( dest. layout . field ( self . cx ( ) , 0 ) . size ) ;
969
+ let elem_layout = dest. layout . field ( self . cx ( ) , 0 ) ;
970
+ let elem_ty = elem_layout . spirv_type ( self . span ( ) , & self ) ;
971
+ let align = dest. align . restrict_for_offset ( elem_layout . size ) ;
949
972
950
973
for i in 0 ..count {
951
- let current = self . inbounds_gep ( start, & [ self . const_usize ( i) ] ) ;
974
+ let current = self . inbounds_gep ( elem_ty , start, & [ self . const_usize ( i) ] ) ;
952
975
cg_elem. val . store (
953
976
& mut self ,
954
977
PlaceRef :: new_sized_aligned ( current, cg_elem. layout , align) ,
@@ -1026,17 +1049,25 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
1026
1049
. unwrap ( ) ;
1027
1050
}
1028
1051
1029
- fn gep ( & mut self , ptr : Self :: Value , indices : & [ Self :: Value ] ) -> Self :: Value {
1030
- self . gep_help ( ptr, indices, false )
1052
+ fn gep ( & mut self , ty : Self :: Type , ptr : Self :: Value , indices : & [ Self :: Value ] ) -> Self :: Value {
1053
+ self . gep_help ( ty , ptr, indices, false )
1031
1054
}
1032
1055
1033
- fn inbounds_gep ( & mut self , ptr : Self :: Value , indices : & [ Self :: Value ] ) -> Self :: Value {
1034
- self . gep_help ( ptr, indices, true )
1056
+ fn inbounds_gep (
1057
+ & mut self ,
1058
+ ty : Self :: Type ,
1059
+ ptr : Self :: Value ,
1060
+ indices : & [ Self :: Value ] ,
1061
+ ) -> Self :: Value {
1062
+ self . gep_help ( ty, ptr, indices, true )
1035
1063
}
1036
1064
1037
- fn struct_gep ( & mut self , ptr : Self :: Value , idx : u64 ) -> Self :: Value {
1065
+ fn struct_gep ( & mut self , ty : Self :: Type , ptr : Self :: Value , idx : u64 ) -> Self :: Value {
1038
1066
let pointee = match self . lookup_type ( ptr. ty ) {
1039
- SpirvType :: Pointer { pointee } => pointee,
1067
+ SpirvType :: Pointer { pointee } => {
1068
+ assert_ty_eq ! ( self , ty, pointee) ;
1069
+ pointee
1070
+ }
1040
1071
other => self . fatal ( & format ! (
1041
1072
"struct_gep not on pointer type: {:?}, index {}" ,
1042
1073
other, idx
@@ -2087,6 +2118,7 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
2087
2118
2088
2119
fn call (
2089
2120
& mut self ,
2121
+ callee_ty : Self :: Type ,
2090
2122
callee : Self :: Value ,
2091
2123
args : & [ Self :: Value ] ,
2092
2124
funclet : Option < & Self :: Funclet > ,
@@ -2104,15 +2136,21 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
2104
2136
SpirvType :: Function {
2105
2137
return_type,
2106
2138
arguments,
2107
- } => ( callee. def ( self ) , return_type, arguments) ,
2139
+ } => {
2140
+ assert_ty_eq ! ( self , callee_ty, callee. ty) ;
2141
+ ( callee. def ( self ) , return_type, arguments)
2142
+ }
2108
2143
2109
2144
SpirvType :: Pointer { pointee } => match self . lookup_type ( pointee) {
2110
2145
SpirvType :: Function {
2111
2146
return_type,
2112
2147
arguments,
2113
2148
} => (
2114
2149
match callee. kind {
2115
- SpirvValueKind :: FnAddr { function } => function,
2150
+ SpirvValueKind :: FnAddr { function } => {
2151
+ assert_ty_eq ! ( self , callee_ty, pointee) ;
2152
+ function
2153
+ }
2116
2154
2117
2155
// Truly indirect call.
2118
2156
_ => {
0 commit comments