diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-01-30 16:23:31 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-01-30 16:23:31 -0700 |
| commit | fb7060d3c2e8ce4d7de5560adf8ec4a26fc5f6e8 (patch) | |
| tree | 3710af0870e1e1d43f44830d6ff3e662761e93ce /src/codegen/llvm.zig | |
| parent | 0c30799d4039c30f95eee29e2c2f8f604e8b9880 (diff) | |
| download | zig-fb7060d3c2e8ce4d7de5560adf8ec4a26fc5f6e8.tar.gz zig-fb7060d3c2e8ce4d7de5560adf8ec4a26fc5f6e8.zip | |
stage2: implement shl_exact and shr_exact
These produce an undefined value when one bits are shifted out.
New AIR instruction: shr_exact.
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, ""); + } } } |
