@@ -41,21 +41,41 @@ impl Lower128Bit {
41
41
let ( basic_blocks, local_decls) = mir. basic_blocks_and_local_decls_mut ( ) ;
42
42
for block in basic_blocks. iter_mut ( ) {
43
43
for i in ( 0 ..block. statements . len ( ) ) . rev ( ) {
44
- let lang_item =
45
- if let Some ( lang_item) = lower_to ( & block. statements [ i] , local_decls, tcx) {
46
- lang_item
44
+ let ( lang_item, rhs_kind) =
45
+ if let Some ( ( lang_item, rhs_kind) ) =
46
+ lower_to ( & block. statements [ i] , local_decls, tcx)
47
+ {
48
+ ( lang_item, rhs_kind)
47
49
} else {
48
50
continue ;
49
51
} ;
50
52
53
+ let rhs_override_ty = rhs_kind. ty ( tcx) ;
54
+ let cast_local =
55
+ match rhs_override_ty {
56
+ None => None ,
57
+ Some ( ty) => {
58
+ let local_decl = LocalDecl :: new_internal (
59
+ ty, block. statements [ i] . source_info . span ) ;
60
+ Some ( local_decls. push ( local_decl) )
61
+ } ,
62
+ } ;
63
+
64
+ let storage_dead = cast_local. map ( |local| {
65
+ Statement {
66
+ source_info : block. statements [ i] . source_info ,
67
+ kind : StatementKind :: StorageDead ( local) ,
68
+ }
69
+ } ) ;
51
70
let after_call = BasicBlockData {
52
- statements : block. statements . drain ( ( i+1 ) ..) . collect ( ) ,
71
+ statements : storage_dead. into_iter ( )
72
+ . chain ( block. statements . drain ( ( i+1 ) ..) ) . collect ( ) ,
53
73
is_cleanup : block. is_cleanup ,
54
74
terminator : block. terminator . take ( ) ,
55
75
} ;
56
76
57
77
let bin_statement = block. statements . pop ( ) . unwrap ( ) ;
58
- let ( source_info, lvalue, lhs, rhs) = match bin_statement {
78
+ let ( source_info, lvalue, lhs, mut rhs) = match bin_statement {
59
79
Statement {
60
80
source_info,
61
81
kind : StatementKind :: Assign (
@@ -71,6 +91,23 @@ impl Lower128Bit {
71
91
_ => bug ! ( "Statement doesn't match pattern any more?" ) ,
72
92
} ;
73
93
94
+ if let Some ( local) = cast_local {
95
+ block. statements . push ( Statement {
96
+ source_info : source_info,
97
+ kind : StatementKind :: StorageLive ( local) ,
98
+ } ) ;
99
+ block. statements . push ( Statement {
100
+ source_info : source_info,
101
+ kind : StatementKind :: Assign (
102
+ Lvalue :: Local ( local) ,
103
+ Rvalue :: Cast (
104
+ CastKind :: Misc ,
105
+ rhs,
106
+ rhs_override_ty. unwrap ( ) ) ) ,
107
+ } ) ;
108
+ rhs = Operand :: Consume ( Lvalue :: Local ( local) ) ;
109
+ }
110
+
74
111
let call_did = check_lang_item_type (
75
112
lang_item, & lvalue, & lhs, & rhs, local_decls, tcx) ;
76
113
@@ -118,7 +155,7 @@ fn check_lang_item_type<'a, 'tcx, D>(
118
155
}
119
156
120
157
fn lower_to < ' a , ' tcx , D > ( statement : & Statement < ' tcx > , local_decls : & D , tcx : TyCtxt < ' a , ' tcx , ' tcx > )
121
- -> Option < LangItem >
158
+ -> Option < ( LangItem , RhsKind ) >
122
159
where D : HasLocalDecls < ' tcx >
123
160
{
124
161
match statement. kind {
@@ -139,6 +176,23 @@ fn lower_to<'a, 'tcx, D>(statement: &Statement<'tcx>, local_decls: &D, tcx: TyCt
139
176
None
140
177
}
141
178
179
+ #[ derive( Copy , Clone ) ]
180
+ enum RhsKind {
181
+ Unchanged ,
182
+ ForceU128 ,
183
+ ForceU32 ,
184
+ }
185
+
186
+ impl RhsKind {
187
+ fn ty < ' a , ' tcx > ( & self , tcx : TyCtxt < ' a , ' tcx , ' tcx > ) -> Option < Ty < ' tcx > > {
188
+ match * self {
189
+ RhsKind :: Unchanged => None ,
190
+ RhsKind :: ForceU128 => Some ( tcx. types . u128 ) ,
191
+ RhsKind :: ForceU32 => Some ( tcx. types . u32 ) ,
192
+ }
193
+ }
194
+ }
195
+
142
196
fn sign_of_128bit ( ty : Ty ) -> Option < bool > {
143
197
match ty. sty {
144
198
TypeVariants :: TyInt ( syntax:: ast:: IntTy :: I128 ) => Some ( true ) ,
@@ -147,39 +201,39 @@ fn sign_of_128bit(ty: Ty) -> Option<bool> {
147
201
}
148
202
}
149
203
150
- fn item_for_op ( bin_op : BinOp , is_signed : bool ) -> Option < LangItem > {
204
+ fn item_for_op ( bin_op : BinOp , is_signed : bool ) -> Option < ( LangItem , RhsKind ) > {
151
205
let i = match ( bin_op, is_signed) {
152
- ( BinOp :: Add , true ) => LangItem :: I128AddFnLangItem ,
153
- ( BinOp :: Add , false ) => LangItem :: U128AddFnLangItem ,
154
- ( BinOp :: Sub , true ) => LangItem :: I128SubFnLangItem ,
155
- ( BinOp :: Sub , false ) => LangItem :: U128SubFnLangItem ,
156
- ( BinOp :: Mul , true ) => LangItem :: I128MulFnLangItem ,
157
- ( BinOp :: Mul , false ) => LangItem :: U128MulFnLangItem ,
158
- ( BinOp :: Div , true ) => LangItem :: I128DivFnLangItem ,
159
- ( BinOp :: Div , false ) => LangItem :: U128DivFnLangItem ,
160
- ( BinOp :: Rem , true ) => LangItem :: I128RemFnLangItem ,
161
- ( BinOp :: Rem , false ) => LangItem :: U128RemFnLangItem ,
162
- ( BinOp :: Shl , true ) => LangItem :: I128ShlFnLangItem ,
163
- ( BinOp :: Shl , false ) => LangItem :: U128ShlFnLangItem ,
164
- ( BinOp :: Shr , true ) => LangItem :: I128ShrFnLangItem ,
165
- ( BinOp :: Shr , false ) => LangItem :: U128ShrFnLangItem ,
206
+ ( BinOp :: Add , true ) => ( LangItem :: I128AddFnLangItem , RhsKind :: Unchanged ) ,
207
+ ( BinOp :: Add , false ) => ( LangItem :: U128AddFnLangItem , RhsKind :: Unchanged ) ,
208
+ ( BinOp :: Sub , true ) => ( LangItem :: I128SubFnLangItem , RhsKind :: Unchanged ) ,
209
+ ( BinOp :: Sub , false ) => ( LangItem :: U128SubFnLangItem , RhsKind :: Unchanged ) ,
210
+ ( BinOp :: Mul , true ) => ( LangItem :: I128MulFnLangItem , RhsKind :: Unchanged ) ,
211
+ ( BinOp :: Mul , false ) => ( LangItem :: U128MulFnLangItem , RhsKind :: Unchanged ) ,
212
+ ( BinOp :: Div , true ) => ( LangItem :: I128DivFnLangItem , RhsKind :: Unchanged ) ,
213
+ ( BinOp :: Div , false ) => ( LangItem :: U128DivFnLangItem , RhsKind :: Unchanged ) ,
214
+ ( BinOp :: Rem , true ) => ( LangItem :: I128RemFnLangItem , RhsKind :: Unchanged ) ,
215
+ ( BinOp :: Rem , false ) => ( LangItem :: U128RemFnLangItem , RhsKind :: Unchanged ) ,
216
+ ( BinOp :: Shl , true ) => ( LangItem :: I128ShlFnLangItem , RhsKind :: ForceU32 ) ,
217
+ ( BinOp :: Shl , false ) => ( LangItem :: U128ShlFnLangItem , RhsKind :: ForceU32 ) ,
218
+ ( BinOp :: Shr , true ) => ( LangItem :: I128ShrFnLangItem , RhsKind :: ForceU32 ) ,
219
+ ( BinOp :: Shr , false ) => ( LangItem :: U128ShrFnLangItem , RhsKind :: ForceU32 ) ,
166
220
_ => return None ,
167
221
} ;
168
222
Some ( i)
169
223
}
170
224
171
- fn item_for_checked_op ( bin_op : BinOp , is_signed : bool ) -> Option < LangItem > {
225
+ fn item_for_checked_op ( bin_op : BinOp , is_signed : bool ) -> Option < ( LangItem , RhsKind ) > {
172
226
let i = match ( bin_op, is_signed) {
173
- ( BinOp :: Add , true ) => LangItem :: I128AddoFnLangItem ,
174
- ( BinOp :: Add , false ) => LangItem :: U128AddoFnLangItem ,
175
- ( BinOp :: Sub , true ) => LangItem :: I128SuboFnLangItem ,
176
- ( BinOp :: Sub , false ) => LangItem :: U128SuboFnLangItem ,
177
- ( BinOp :: Mul , true ) => LangItem :: I128MuloFnLangItem ,
178
- ( BinOp :: Mul , false ) => LangItem :: U128MuloFnLangItem ,
179
- ( BinOp :: Shl , true ) => LangItem :: I128ShloFnLangItem ,
180
- ( BinOp :: Shl , false ) => LangItem :: U128ShloFnLangItem ,
181
- ( BinOp :: Shr , true ) => LangItem :: I128ShroFnLangItem ,
182
- ( BinOp :: Shr , false ) => LangItem :: U128ShroFnLangItem ,
227
+ ( BinOp :: Add , true ) => ( LangItem :: I128AddoFnLangItem , RhsKind :: Unchanged ) ,
228
+ ( BinOp :: Add , false ) => ( LangItem :: U128AddoFnLangItem , RhsKind :: Unchanged ) ,
229
+ ( BinOp :: Sub , true ) => ( LangItem :: I128SuboFnLangItem , RhsKind :: Unchanged ) ,
230
+ ( BinOp :: Sub , false ) => ( LangItem :: U128SuboFnLangItem , RhsKind :: Unchanged ) ,
231
+ ( BinOp :: Mul , true ) => ( LangItem :: I128MuloFnLangItem , RhsKind :: Unchanged ) ,
232
+ ( BinOp :: Mul , false ) => ( LangItem :: U128MuloFnLangItem , RhsKind :: Unchanged ) ,
233
+ ( BinOp :: Shl , true ) => ( LangItem :: I128ShloFnLangItem , RhsKind :: ForceU128 ) ,
234
+ ( BinOp :: Shl , false ) => ( LangItem :: U128ShloFnLangItem , RhsKind :: ForceU128 ) ,
235
+ ( BinOp :: Shr , true ) => ( LangItem :: I128ShroFnLangItem , RhsKind :: ForceU128 ) ,
236
+ ( BinOp :: Shr , false ) => ( LangItem :: U128ShroFnLangItem , RhsKind :: ForceU128 ) ,
183
237
_ => bug ! ( "That should be all the checked ones?" ) ,
184
238
} ;
185
239
Some ( i)
0 commit comments