diff options
Diffstat (limited to 'src/codegen/llvm.zig')
| -rw-r--r-- | src/codegen/llvm.zig | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index df64c0c912..81742d4866 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -2047,7 +2047,8 @@ pub const FuncGen = struct { .bit_and, .bool_and => try self.airAnd(inst), .bit_or, .bool_or => try self.airOr(inst), .xor => try self.airXor(inst), - .shr => try self.airShr(inst), + .shr => try self.airShr(inst, false), + .shr_exact => try self.airShr(inst, true), .cmp_eq => try self.airCmp(inst, .eq), .cmp_gt => try self.airCmp(inst, .gt), @@ -3633,7 +3634,7 @@ pub const FuncGen = struct { return self.builder.buildUShlSat(lhs, casted_rhs, ""); } - fn airShr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { + fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) !?*const llvm.Value { if (self.liveness.isUnused(inst)) return null; const bin_op = self.air.instructions.items(.data)[inst].bin_op; @@ -3645,11 +3646,20 @@ pub const FuncGen = struct { self.builder.buildZExt(rhs, try self.dg.llvmType(lhs_type), "") else rhs; + const is_signed_int = self.air.typeOfIndex(inst).isSignedInt(); - if (self.air.typeOfIndex(inst).isSignedInt()) { - return self.builder.buildAShr(lhs, casted_rhs, ""); + if (is_exact) { + if (is_signed_int) { + return self.builder.buildAShrExact(lhs, casted_rhs, ""); + } else { + return self.builder.buildLShrExact(lhs, casted_rhs, ""); + } } else { - return self.builder.buildLShr(lhs, casted_rhs, ""); + if (is_signed_int) { + return self.builder.buildAShr(lhs, casted_rhs, ""); + } else { + return self.builder.buildLShr(lhs, casted_rhs, ""); + } } } |
