diff --git a/src/codegen/llvm/Builder.zig b/src/codegen/llvm/Builder.zig index 12ecd2ec38..a38882b647 100644 --- a/src/codegen/llvm/Builder.zig +++ b/src/codegen/llvm/Builder.zig @@ -14734,39 +14734,23 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co }, adapter); }, .add, - .@"add nsw", - .@"add nuw", - .@"add nuw nsw", .@"and", .fadd, .fdiv, .fmul, .mul, - .@"mul nsw", - .@"mul nuw", - .@"mul nuw nsw", .frem, .fsub, .sdiv, - .@"sdiv exact", .sub, - .@"sub nsw", - .@"sub nuw", - .@"sub nuw nsw", .udiv, - .@"udiv exact", .xor, .shl, - .@"shl nsw", - .@"shl nuw", - .@"shl nuw nsw", .lshr, - .@"lshr exact", .@"or", .urem, .srem, .ashr, - .@"ashr exact", => |kind| { const extra = func.extraData(Function.Instruction.Binary, datas[instr_index]); try function_block.writeAbbrev(FunctionBlock.Binary{ @@ -14775,6 +14759,56 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co .rhs = adapter.getOffsetValueIndex(extra.rhs), }); }, + .@"sdiv exact", + .@"udiv exact", + .@"lshr exact", + .@"ashr exact", + => |kind| { + const extra = func.extraData(Function.Instruction.Binary, datas[instr_index]); + try function_block.writeAbbrev(FunctionBlock.BinaryExact{ + .opcode = kind.toBinaryOpcode(), + .lhs = adapter.getOffsetValueIndex(extra.lhs), + .rhs = adapter.getOffsetValueIndex(extra.rhs), + }); + }, + .@"add nsw", + .@"add nuw", + .@"add nuw nsw", + .@"mul nsw", + .@"mul nuw", + .@"mul nuw nsw", + .@"sub nsw", + .@"sub nuw", + .@"sub nuw nsw", + .@"shl nsw", + .@"shl nuw", + .@"shl nuw nsw", + => |kind| { + const extra = func.extraData(Function.Instruction.Binary, datas[instr_index]); + try function_block.writeAbbrev(FunctionBlock.BinaryNoWrap{ + .opcode = kind.toBinaryOpcode(), + .lhs = adapter.getOffsetValueIndex(extra.lhs), + .rhs = adapter.getOffsetValueIndex(extra.rhs), + .flags = switch (kind) { + .@"add nsw", + .@"mul nsw", + .@"sub nsw", + .@"shl nsw", + => .{ .no_unsigned_wrap = false, .no_signed_wrap = true }, + .@"add nuw", + .@"mul nuw", + .@"sub nuw", + .@"shl nuw", + => .{ .no_unsigned_wrap = true, .no_signed_wrap = false }, + .@"add nuw nsw", + .@"mul nuw nsw", + .@"sub nuw nsw", + .@"shl nuw nsw", + => .{ .no_unsigned_wrap = true, .no_signed_wrap = true }, + else => unreachable, + }, + }); + }, .@"fadd fast", .@"fdiv fast", .@"fmul fast", diff --git a/src/codegen/llvm/ir.zig b/src/codegen/llvm/ir.zig index 8e3d20a63a..6a7c6c6857 100644 --- a/src/codegen/llvm/ir.zig +++ b/src/codegen/llvm/ir.zig @@ -1102,6 +1102,8 @@ pub const FunctionBlock = struct { FNeg, FNegFast, Binary, + BinaryNoWrap, + BinaryExact, BinaryFast, Cmp, CmpFast, @@ -1232,6 +1234,40 @@ pub const FunctionBlock = struct { opcode: BinaryOpcode, }; + pub const BinaryNoWrap = struct { + const BinaryOpcode = Builder.BinaryOpcode; + pub const ops = [_]AbbrevOp{ + .{ .literal = 2 }, + ValueAbbrev, + ValueAbbrev, + .{ .fixed = @bitSizeOf(BinaryOpcode) }, + .{ .fixed = 2 }, + }; + + lhs: u32, + rhs: u32, + opcode: BinaryOpcode, + flags: packed struct(u2) { + no_unsigned_wrap: bool, + no_signed_wrap: bool, + }, + }; + + pub const BinaryExact = struct { + const BinaryOpcode = Builder.BinaryOpcode; + pub const ops = [_]AbbrevOp{ + .{ .literal = 2 }, + ValueAbbrev, + ValueAbbrev, + .{ .fixed = @bitSizeOf(BinaryOpcode) }, + .{ .literal = 1 }, + }; + + lhs: u32, + rhs: u32, + opcode: BinaryOpcode, + }; + pub const BinaryFast = struct { const BinaryOpcode = Builder.BinaryOpcode; pub const ops = [_]AbbrevOp{