Commit 637b1d606d

antlilja <liljaanton2001@gmail.com>
2024-04-05 13:20:14
LLVM Builder: Emit binary op optional flags for exact and no wrap
1 parent 3942083
Changed files (2)
src
codegen
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",
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{