@@ -368,11 +368,21 @@ def process_Arith(self, insn):
368
368
return self .llbuilder .fptosi (llvalue , self .llty_of_type (insn .type ),
369
369
name = insn .name )
370
370
elif isinstance (insn .op , ast .LShift ):
371
- return self .llbuilder .shl (self .map (insn .lhs ()), self .map (insn .rhs ()),
372
- name = insn .name )
371
+ lllhs , llrhs = map (self .map , (insn .lhs (), insn .rhs ()))
372
+ llrhs_max = ll .Constant (llrhs .type , builtins .get_int_width (insn .lhs ().type ))
373
+ llrhs_overflow = self .llbuilder .icmp_signed ('>=' , llrhs , llrhs_max )
374
+ llvalue_zero = ll .Constant (lllhs .type , 0 )
375
+ llvalue = self .llbuilder .shl (lllhs , llrhs )
376
+ return self .llbuilder .select (llrhs_overflow , llvalue_zero , llvalue ,
377
+ name = insn .name )
373
378
elif isinstance (insn .op , ast .RShift ):
374
- return self .llbuilder .ashr (self .map (insn .lhs ()), self .map (insn .rhs ()),
375
- name = insn .name )
379
+ lllhs , llrhs = map (self .map , (insn .lhs (), insn .rhs ()))
380
+ llrhs_max = ll .Constant (llrhs .type , builtins .get_int_width (insn .lhs ().type ) - 1 )
381
+ llrhs_overflow = self .llbuilder .icmp_signed ('>' , llrhs , llrhs_max )
382
+ llvalue = self .llbuilder .ashr (lllhs , llrhs )
383
+ llvalue_max = self .llbuilder .ashr (lllhs , llrhs_max ) # preserve sign bit
384
+ return self .llbuilder .select (llrhs_overflow , llvalue_max , llvalue ,
385
+ name = insn .name )
376
386
elif isinstance (insn .op , ast .BitAnd ):
377
387
return self .llbuilder .and_ (self .map (insn .lhs ()), self .map (insn .rhs ()),
378
388
name = insn .name )
0 commit comments