Commit c231d94960

antlilja <liljaanton2001@gmail.com>
2024-02-29 19:59:55
LLVM: Remove deprecated or soon to be deprecated constant expressions
1 parent 3648d7d
Changed files (2)
src
codegen
src/codegen/llvm/Builder.zig
@@ -5694,7 +5694,7 @@ pub const WipFunction = struct {
     ) Allocator.Error!Value {
         const val_ty = val.typeOfWip(self);
         if (val_ty == ty) return val;
-        return self.cast(self.builder.convTag(Instruction.Tag, signedness, val_ty, ty), val, ty, name);
+        return self.cast(self.builder.convTag(signedness, val_ty, ty), val, ty, name);
     }
 
     pub fn cast(
@@ -6891,39 +6891,19 @@ pub const Constant = enum(u32) {
         dso_local_equivalent,
         no_cfi,
         trunc,
-        zext,
-        sext,
-        fptrunc,
-        fpext,
-        fptoui,
-        fptosi,
-        uitofp,
-        sitofp,
         ptrtoint,
         inttoptr,
         bitcast,
         addrspacecast,
         getelementptr,
         @"getelementptr inbounds",
-        icmp,
-        fcmp,
-        extractelement,
-        insertelement,
-        shufflevector,
         add,
         @"add nsw",
         @"add nuw",
         sub,
         @"sub nsw",
         @"sub nuw",
-        mul,
-        @"mul nsw",
-        @"mul nuw",
         shl,
-        lshr,
-        ashr,
-        @"and",
-        @"or",
         xor,
         @"asm",
         @"asm sideeffect",
@@ -6952,15 +6932,7 @@ pub const Constant = enum(u32) {
                 .@"sub nsw",
                 .@"sub nuw",
                 => .sub,
-                .mul,
-                .@"mul nsw",
-                .@"mul nuw",
-                => .mul,
                 .shl => .shl,
-                .lshr => .lshr,
-                .ashr => .ashr,
-                .@"and" => .@"and",
-                .@"or" => .@"or",
                 .xor => .xor,
                 else => unreachable,
             };
@@ -6969,14 +6941,6 @@ pub const Constant = enum(u32) {
         pub fn toCastOpcode(self: Tag) CastOpcode {
             return switch (self) {
                 .trunc => .trunc,
-                .zext => .zext,
-                .sext => .sext,
-                .fptoui => .fptoui,
-                .fptosi => .fptosi,
-                .uitofp => .uitofp,
-                .sitofp => .sitofp,
-                .fptrunc => .fptrunc,
-                .fpext => .fpext,
                 .ptrtoint => .ptrtoint,
                 .inttoptr => .inttoptr,
                 .bitcast => .bitcast,
@@ -7051,29 +7015,6 @@ pub const Constant = enum(u32) {
         pub const Info = packed struct(u32) { indices_len: u16, inrange: InRangeIndex };
     };
 
-    pub const Compare = extern struct {
-        cond: u32,
-        lhs: Constant,
-        rhs: Constant,
-    };
-
-    pub const ExtractElement = extern struct {
-        val: Constant,
-        index: Constant,
-    };
-
-    pub const InsertElement = extern struct {
-        val: Constant,
-        elem: Constant,
-        index: Constant,
-    };
-
-    pub const ShuffleVector = extern struct {
-        lhs: Constant,
-        rhs: Constant,
-        mask: Constant,
-    };
-
     pub const Binary = extern struct {
         lhs: Constant,
         rhs: Constant,
@@ -7149,14 +7090,6 @@ pub const Constant = enum(u32) {
                     => builder.ptrTypeAssumeCapacity(@as(Function.Index, @enumFromInt(item.data))
                         .ptrConst(builder).global.ptrConst(builder).addr_space),
                     .trunc,
-                    .zext,
-                    .sext,
-                    .fptrunc,
-                    .fpext,
-                    .fptoui,
-                    .fptosi,
-                    .uitofp,
-                    .sitofp,
                     .ptrtoint,
                     .inttoptr,
                     .bitcast,
@@ -7176,35 +7109,13 @@ pub const Constant = enum(u32) {
                         };
                         return base_ty;
                     },
-                    .icmp,
-                    .fcmp,
-                    => builder.constantExtraData(Compare, item.data).lhs.typeOf(builder)
-                        .changeScalarAssumeCapacity(.i1, builder),
-                    .extractelement => builder.constantExtraData(ExtractElement, item.data)
-                        .val.typeOf(builder).childType(builder),
-                    .insertelement => builder.constantExtraData(InsertElement, item.data)
-                        .val.typeOf(builder),
-                    .shufflevector => {
-                        const extra = builder.constantExtraData(ShuffleVector, item.data);
-                        return extra.lhs.typeOf(builder).changeLengthAssumeCapacity(
-                            extra.mask.typeOf(builder).vectorLen(builder),
-                            builder,
-                        );
-                    },
                     .add,
                     .@"add nsw",
                     .@"add nuw",
                     .sub,
                     .@"sub nsw",
                     .@"sub nuw",
-                    .mul,
-                    .@"mul nsw",
-                    .@"mul nuw",
                     .shl,
-                    .lshr,
-                    .ashr,
-                    .@"and",
-                    .@"or",
                     .xor,
                     => builder.constantExtraData(Binary, item.data).lhs.typeOf(builder),
                     .@"asm",
@@ -7516,14 +7427,6 @@ pub const Constant = enum(u32) {
                         });
                     },
                     .trunc,
-                    .zext,
-                    .sext,
-                    .fptrunc,
-                    .fpext,
-                    .fptoui,
-                    .fptosi,
-                    .uitofp,
-                    .sitofp,
                     .ptrtoint,
                     .inttoptr,
                     .bitcast,
@@ -7550,61 +7453,13 @@ pub const Constant = enum(u32) {
                         for (indices) |index| try writer.print(", {%}", .{index.fmt(data.builder)});
                         try writer.writeByte(')');
                     },
-                    inline .icmp,
-                    .fcmp,
-                    => |tag| {
-                        const extra = data.builder.constantExtraData(Compare, item.data);
-                        try writer.print("{s} {s} ({%}, {%})", .{
-                            @tagName(tag),
-                            @tagName(@as(switch (tag) {
-                                .icmp => IntegerCondition,
-                                .fcmp => FloatCondition,
-                                else => unreachable,
-                            }, @enumFromInt(extra.cond))),
-                            extra.lhs.fmt(data.builder),
-                            extra.rhs.fmt(data.builder),
-                        });
-                    },
-                    .extractelement => |tag| {
-                        const extra = data.builder.constantExtraData(ExtractElement, item.data);
-                        try writer.print("{s} ({%}, {%})", .{
-                            @tagName(tag),
-                            extra.val.fmt(data.builder),
-                            extra.index.fmt(data.builder),
-                        });
-                    },
-                    .insertelement => |tag| {
-                        const extra = data.builder.constantExtraData(InsertElement, item.data);
-                        try writer.print("{s} ({%}, {%}, {%})", .{
-                            @tagName(tag),
-                            extra.val.fmt(data.builder),
-                            extra.elem.fmt(data.builder),
-                            extra.index.fmt(data.builder),
-                        });
-                    },
-                    .shufflevector => |tag| {
-                        const extra = data.builder.constantExtraData(ShuffleVector, item.data);
-                        try writer.print("{s} ({%}, {%}, {%})", .{
-                            @tagName(tag),
-                            extra.lhs.fmt(data.builder),
-                            extra.rhs.fmt(data.builder),
-                            extra.mask.fmt(data.builder),
-                        });
-                    },
                     .add,
                     .@"add nsw",
                     .@"add nuw",
                     .sub,
                     .@"sub nsw",
                     .@"sub nuw",
-                    .mul,
-                    .@"mul nsw",
-                    .@"mul nuw",
                     .shl,
-                    .lshr,
-                    .ashr,
-                    .@"and",
-                    .@"or",
                     .xor,
                     => |tag| {
                         const extra = data.builder.constantExtraData(Binary, item.data);
@@ -9278,21 +9133,19 @@ pub fn noCfiValue(self: *Builder, function: Function.Index) Allocator.Error!Valu
 
 pub fn convConst(
     self: *Builder,
-    signedness: Constant.Cast.Signedness,
     val: Constant,
     ty: Type,
 ) Allocator.Error!Constant {
     try self.ensureUnusedConstantCapacity(1, Constant.Cast, 0);
-    return self.convConstAssumeCapacity(signedness, val, ty);
+    return self.convConstAssumeCapacity(val, ty);
 }
 
 pub fn convValue(
     self: *Builder,
-    signedness: Constant.Cast.Signedness,
     val: Constant,
     ty: Type,
 ) Allocator.Error!Value {
-    return (try self.convConst(signedness, val, ty)).toValue();
+    return (try self.convConst(val, ty)).toValue();
 }
 
 pub fn castConst(self: *Builder, tag: Constant.Tag, val: Constant, ty: Type) Allocator.Error!Constant {
@@ -9328,92 +9181,6 @@ pub fn gepValue(
     return (try self.gepConst(kind, ty, base, inrange, indices)).toValue();
 }
 
-pub fn icmpConst(
-    self: *Builder,
-    cond: IntegerCondition,
-    lhs: Constant,
-    rhs: Constant,
-) Allocator.Error!Constant {
-    try self.ensureUnusedConstantCapacity(1, Constant.Compare, 0);
-    return self.icmpConstAssumeCapacity(cond, lhs, rhs);
-}
-
-pub fn icmpValue(
-    self: *Builder,
-    cond: IntegerCondition,
-    lhs: Constant,
-    rhs: Constant,
-) Allocator.Error!Value {
-    return (try self.icmpConst(cond, lhs, rhs)).toValue();
-}
-
-pub fn fcmpConst(
-    self: *Builder,
-    cond: FloatCondition,
-    lhs: Constant,
-    rhs: Constant,
-) Allocator.Error!Constant {
-    try self.ensureUnusedConstantCapacity(1, Constant.Compare, 0);
-    return self.icmpConstAssumeCapacity(cond, lhs, rhs);
-}
-
-pub fn fcmpValue(
-    self: *Builder,
-    cond: FloatCondition,
-    lhs: Constant,
-    rhs: Constant,
-) Allocator.Error!Value {
-    return (try self.fcmpConst(cond, lhs, rhs)).toValue();
-}
-
-pub fn extractElementConst(self: *Builder, val: Constant, index: Constant) Allocator.Error!Constant {
-    try self.ensureUnusedConstantCapacity(1, Constant.ExtractElement, 0);
-    return self.extractElementConstAssumeCapacity(val, index);
-}
-
-pub fn extractElementValue(self: *Builder, val: Constant, index: Constant) Allocator.Error!Value {
-    return (try self.extractElementConst(val, index)).toValue();
-}
-
-pub fn insertElementConst(
-    self: *Builder,
-    val: Constant,
-    elem: Constant,
-    index: Constant,
-) Allocator.Error!Constant {
-    try self.ensureUnusedConstantCapacity(1, Constant.InsertElement, 0);
-    return self.insertElementConstAssumeCapacity(val, elem, index);
-}
-
-pub fn insertElementValue(
-    self: *Builder,
-    val: Constant,
-    elem: Constant,
-    index: Constant,
-) Allocator.Error!Value {
-    return (try self.insertElementConst(val, elem, index)).toValue();
-}
-
-pub fn shuffleVectorConst(
-    self: *Builder,
-    lhs: Constant,
-    rhs: Constant,
-    mask: Constant,
-) Allocator.Error!Constant {
-    try self.ensureUnusedTypeCapacity(1, Type.Array, 0);
-    try self.ensureUnusedConstantCapacity(1, Constant.ShuffleVector, 0);
-    return self.shuffleVectorConstAssumeCapacity(lhs, rhs, mask);
-}
-
-pub fn shuffleVectorValue(
-    self: *Builder,
-    lhs: Constant,
-    rhs: Constant,
-    mask: Constant,
-) Allocator.Error!Value {
-    return (try self.shuffleVectorConst(lhs, rhs, mask)).toValue();
-}
-
 pub fn binConst(
     self: *Builder,
     tag: Constant.Tag,
@@ -11390,11 +11157,10 @@ fn noCfiConstAssumeCapacity(self: *Builder, function: Function.Index) Constant {
 
 fn convTag(
     self: *Builder,
-    comptime Tag: type,
     signedness: Constant.Cast.Signedness,
     val_ty: Type,
     ty: Type,
-) Tag {
+) Function.Instruction.Tag {
     assert(val_ty != ty);
     return switch (val_ty.scalarTag(self)) {
         .simple => switch (ty.scalarTag(self)) {
@@ -11437,15 +11203,38 @@ fn convTag(
     };
 }
 
+fn convConstTag(
+    self: *Builder,
+    val_ty: Type,
+    ty: Type,
+) Constant.Tag {
+    assert(val_ty != ty);
+    return switch (val_ty.scalarTag(self)) {
+        .integer => switch (ty.scalarTag(self)) {
+            .integer => switch (std.math.order(val_ty.scalarBits(self), ty.scalarBits(self))) {
+                .gt => .trunc,
+                else => unreachable,
+            },
+            .pointer => .inttoptr,
+            else => unreachable,
+        },
+        .pointer => switch (ty.scalarTag(self)) {
+            .integer => .ptrtoint,
+            .pointer => .addrspacecast,
+            else => unreachable,
+        },
+        else => unreachable,
+    };
+}
+
 fn convConstAssumeCapacity(
     self: *Builder,
-    signedness: Constant.Cast.Signedness,
     val: Constant,
     ty: Type,
 ) Constant {
     const val_ty = val.typeOf(self);
     if (val_ty == ty) return val;
-    return self.castConstAssumeCapacity(self.convTag(Constant.Tag, signedness, val_ty, ty), val, ty);
+    return self.castConstAssumeCapacity(self.convConstTag(val_ty, ty), val, ty);
 }
 
 fn castConstAssumeCapacity(self: *Builder, tag: Constant.Tag, val: Constant, ty: Type) Constant {
@@ -11570,179 +11359,6 @@ fn gepConstAssumeCapacity(
     return @enumFromInt(gop.index);
 }
 
-fn icmpConstAssumeCapacity(
-    self: *Builder,
-    cond: IntegerCondition,
-    lhs: Constant,
-    rhs: Constant,
-) Constant {
-    const Adapter = struct {
-        builder: *const Builder,
-        pub fn hash(_: @This(), key: Constant.Compare) u32 {
-            return @truncate(std.hash.Wyhash.hash(
-                std.hash.uint32(@intFromEnum(Constant.tag.icmp)),
-                std.mem.asBytes(&key),
-            ));
-        }
-        pub fn eql(ctx: @This(), lhs_key: Constant.Compare, _: void, rhs_index: usize) bool {
-            if (ctx.builder.constant_items.items(.tag)[rhs_index] != .icmp) return false;
-            const rhs_data = ctx.builder.constant_items.items(.data)[rhs_index];
-            const rhs_extra = ctx.builder.constantExtraData(Constant.Compare, rhs_data);
-            return std.meta.eql(lhs_key, rhs_extra);
-        }
-    };
-    const data = Constant.Compare{ .cond = @intFromEnum(cond), .lhs = lhs, .rhs = rhs };
-    const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self });
-    if (!gop.found_existing) {
-        gop.key_ptr.* = {};
-        gop.value_ptr.* = {};
-        self.constant_items.appendAssumeCapacity(.{
-            .tag = .icmp,
-            .data = self.addConstantExtraAssumeCapacity(data),
-        });
-    }
-    return @enumFromInt(gop.index);
-}
-
-fn fcmpConstAssumeCapacity(
-    self: *Builder,
-    cond: FloatCondition,
-    lhs: Constant,
-    rhs: Constant,
-) Constant {
-    const Adapter = struct {
-        builder: *const Builder,
-        pub fn hash(_: @This(), key: Constant.Compare) u32 {
-            return @truncate(std.hash.Wyhash.hash(
-                std.hash.uint32(@intFromEnum(Constant.tag.fcmp)),
-                std.mem.asBytes(&key),
-            ));
-        }
-        pub fn eql(ctx: @This(), lhs_key: Constant.Compare, _: void, rhs_index: usize) bool {
-            if (ctx.builder.constant_items.items(.tag)[rhs_index] != .fcmp) return false;
-            const rhs_data = ctx.builder.constant_items.items(.data)[rhs_index];
-            const rhs_extra = ctx.builder.constantExtraData(Constant.Compare, rhs_data);
-            return std.meta.eql(lhs_key, rhs_extra);
-        }
-    };
-    const data = Constant.Compare{ .cond = @intFromEnum(cond), .lhs = lhs, .rhs = rhs };
-    const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self });
-    if (!gop.found_existing) {
-        gop.key_ptr.* = {};
-        gop.value_ptr.* = {};
-        self.constant_items.appendAssumeCapacity(.{
-            .tag = .fcmp,
-            .data = self.addConstantExtraAssumeCapacity(data),
-        });
-    }
-    return @enumFromInt(gop.index);
-}
-
-fn extractElementConstAssumeCapacity(
-    self: *Builder,
-    val: Constant,
-    index: Constant,
-) Constant {
-    const Adapter = struct {
-        builder: *const Builder,
-        pub fn hash(_: @This(), key: Constant.ExtractElement) u32 {
-            return @truncate(std.hash.Wyhash.hash(
-                comptime std.hash.uint32(@intFromEnum(Constant.Tag.extractelement)),
-                std.mem.asBytes(&key),
-            ));
-        }
-        pub fn eql(ctx: @This(), lhs_key: Constant.ExtractElement, _: void, rhs_index: usize) bool {
-            if (ctx.builder.constant_items.items(.tag)[rhs_index] != .extractelement) return false;
-            const rhs_data = ctx.builder.constant_items.items(.data)[rhs_index];
-            const rhs_extra = ctx.builder.constantExtraData(Constant.ExtractElement, rhs_data);
-            return std.meta.eql(lhs_key, rhs_extra);
-        }
-    };
-    const data = Constant.ExtractElement{ .val = val, .index = index };
-    const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self });
-    if (!gop.found_existing) {
-        gop.key_ptr.* = {};
-        gop.value_ptr.* = {};
-        self.constant_items.appendAssumeCapacity(.{
-            .tag = .extractelement,
-            .data = self.addConstantExtraAssumeCapacity(data),
-        });
-    }
-    return @enumFromInt(gop.index);
-}
-
-fn insertElementConstAssumeCapacity(
-    self: *Builder,
-    val: Constant,
-    elem: Constant,
-    index: Constant,
-) Constant {
-    const Adapter = struct {
-        builder: *const Builder,
-        pub fn hash(_: @This(), key: Constant.InsertElement) u32 {
-            return @truncate(std.hash.Wyhash.hash(
-                comptime std.hash.uint32(@intFromEnum(Constant.Tag.insertelement)),
-                std.mem.asBytes(&key),
-            ));
-        }
-        pub fn eql(ctx: @This(), lhs_key: Constant.InsertElement, _: void, rhs_index: usize) bool {
-            if (ctx.builder.constant_items.items(.tag)[rhs_index] != .insertelement) return false;
-            const rhs_data = ctx.builder.constant_items.items(.data)[rhs_index];
-            const rhs_extra = ctx.builder.constantExtraData(Constant.InsertElement, rhs_data);
-            return std.meta.eql(lhs_key, rhs_extra);
-        }
-    };
-    const data = Constant.InsertElement{ .val = val, .elem = elem, .index = index };
-    const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self });
-    if (!gop.found_existing) {
-        gop.key_ptr.* = {};
-        gop.value_ptr.* = {};
-        self.constant_items.appendAssumeCapacity(.{
-            .tag = .insertelement,
-            .data = self.addConstantExtraAssumeCapacity(data),
-        });
-    }
-    return @enumFromInt(gop.index);
-}
-
-fn shuffleVectorConstAssumeCapacity(
-    self: *Builder,
-    lhs: Constant,
-    rhs: Constant,
-    mask: Constant,
-) Constant {
-    assert(lhs.typeOf(self).isVector(self.builder));
-    assert(lhs.typeOf(self) == rhs.typeOf(self));
-    assert(mask.typeOf(self).scalarType(self).isInteger(self));
-    _ = lhs.typeOf(self).changeLengthAssumeCapacity(mask.typeOf(self).vectorLen(self), self);
-    const Adapter = struct {
-        builder: *const Builder,
-        pub fn hash(_: @This(), key: Constant.ShuffleVector) u32 {
-            return @truncate(std.hash.Wyhash.hash(
-                comptime std.hash.uint32(@intFromEnum(Constant.Tag.shufflevector)),
-                std.mem.asBytes(&key),
-            ));
-        }
-        pub fn eql(ctx: @This(), lhs_key: Constant.ShuffleVector, _: void, rhs_index: usize) bool {
-            if (ctx.builder.constant_items.items(.tag)[rhs_index] != .shufflevector) return false;
-            const rhs_data = ctx.builder.constant_items.items(.data)[rhs_index];
-            const rhs_extra = ctx.builder.constantExtraData(Constant.ShuffleVector, rhs_data);
-            return std.meta.eql(lhs_key, rhs_extra);
-        }
-    };
-    const data = Constant.ShuffleVector{ .lhs = lhs, .rhs = rhs, .mask = mask };
-    const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self });
-    if (!gop.found_existing) {
-        gop.key_ptr.* = {};
-        gop.value_ptr.* = {};
-        self.constant_items.appendAssumeCapacity(.{
-            .tag = .shufflevector,
-            .data = self.addConstantExtraAssumeCapacity(data),
-        });
-    }
-    return @enumFromInt(gop.index);
-}
-
 fn binConstAssumeCapacity(
     self: *Builder,
     tag: Constant.Tag,
@@ -11756,14 +11372,7 @@ fn binConstAssumeCapacity(
         .sub,
         .@"sub nsw",
         .@"sub nuw",
-        .mul,
-        .@"mul nsw",
-        .@"mul nuw",
         .shl,
-        .lshr,
-        .ashr,
-        .@"and",
-        .@"or",
         .xor,
         => {},
         else => unreachable,
@@ -13938,16 +13547,8 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co
                     .bitcast,
                     .inttoptr,
                     .ptrtoint,
-                    .fptosi,
-                    .fptoui,
-                    .sitofp,
-                    .uitofp,
                     .addrspacecast,
-                    .fptrunc,
                     .trunc,
-                    .fpext,
-                    .sext,
-                    .zext,
                     => |tag| {
                         const extra = self.constantExtraData(Constant.Cast, data);
                         try constants_block.writeAbbrevAdapted(Constants.Cast{
@@ -13962,14 +13563,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co
                     .sub,
                     .@"sub nsw",
                     .@"sub nuw",
-                    .mul,
-                    .@"mul nsw",
-                    .@"mul nuw",
                     .shl,
-                    .lshr,
-                    .ashr,
-                    .@"and",
-                    .@"or",
                     .xor,
                     => |tag| {
                         const extra = self.constantExtraData(Constant.Binary, data);
@@ -13979,55 +13573,6 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co
                             .rhs = extra.rhs,
                         }, constant_adapter);
                     },
-                    .icmp,
-                    .fcmp,
-                    => {
-                        const extra = self.constantExtraData(Constant.Compare, data);
-                        try constants_block.writeAbbrevAdapted(Constants.Cmp{
-                            .ty = extra.lhs.typeOf(self),
-                            .lhs = extra.lhs,
-                            .rhs = extra.rhs,
-                            .pred = extra.cond,
-                        }, constant_adapter);
-                    },
-                    .extractelement => {
-                        const extra = self.constantExtraData(Constant.ExtractElement, data);
-                        try constants_block.writeAbbrevAdapted(Constants.ExtractElement{
-                            .val_type = extra.val.typeOf(self),
-                            .val = extra.val,
-                            .index_type = extra.index.typeOf(self),
-                            .index = extra.index,
-                        }, constant_adapter);
-                    },
-                    .insertelement => {
-                        const extra = self.constantExtraData(Constant.InsertElement, data);
-                        try constants_block.writeAbbrevAdapted(Constants.InsertElement{
-                            .val = extra.val,
-                            .elem = extra.elem,
-                            .index_type = extra.index.typeOf(self),
-                            .index = extra.index,
-                        }, constant_adapter);
-                    },
-                    .shufflevector => {
-                        const extra = self.constantExtraData(Constant.ShuffleVector, data);
-                        const ty = constant.typeOf(self);
-                        const lhs_type = extra.lhs.typeOf(self);
-                        // Check if instruction is widening, truncating or not
-                        if (ty == lhs_type) {
-                            try constants_block.writeAbbrevAdapted(Constants.ShuffleVector{
-                                .lhs = extra.lhs,
-                                .rhs = extra.rhs,
-                                .mask = extra.mask,
-                            }, constant_adapter);
-                        } else {
-                            try constants_block.writeAbbrevAdapted(Constants.ShuffleVectorEx{
-                                .ty = ty,
-                                .lhs = extra.lhs,
-                                .rhs = extra.rhs,
-                                .mask = extra.mask,
-                            }, constant_adapter);
-                        }
-                    },
                     .getelementptr,
                     .@"getelementptr inbounds",
                     => |tag| {
src/codegen/llvm.zig
@@ -3665,6 +3665,124 @@ pub const Object = struct {
         );
     }
 
+    fn lowerValueToInt(o: *Object, llvm_int_ty: Builder.Type, arg_val: InternPool.Index) Error!Builder.Constant {
+        const mod = o.module;
+        const ip = &mod.intern_pool;
+        const target = mod.getTarget();
+
+        const val = Value.fromInterned(arg_val);
+        const val_key = ip.indexToKey(val.toIntern());
+
+        if (val.isUndefDeep(mod)) return o.builder.undefConst(llvm_int_ty);
+
+        const ty = Type.fromInterned(val_key.typeOf());
+        switch (val_key) {
+            .extern_func => |extern_func| {
+                const fn_decl_index = extern_func.decl;
+                const function_index = try o.resolveLlvmFunction(fn_decl_index);
+                const ptr = function_index.ptrConst(&o.builder).global.toConst();
+                return o.builder.convConst(ptr, llvm_int_ty);
+            },
+            .func => |func| {
+                const fn_decl_index = func.owner_decl;
+                const function_index = try o.resolveLlvmFunction(fn_decl_index);
+                const ptr = function_index.ptrConst(&o.builder).global.toConst();
+                return o.builder.convConst(ptr, llvm_int_ty);
+            },
+            .ptr => return o.builder.convConst(try o.lowerPtr(arg_val, 0), llvm_int_ty),
+            .aggregate => switch (ip.indexToKey(ty.toIntern())) {
+                .struct_type => {
+                    const struct_type = ip.loadStructType(ty.toIntern());
+                    assert(struct_type.haveLayout(ip));
+                    assert(struct_type.layout == .@"packed");
+                    comptime assert(Type.packed_struct_layout_version == 2);
+                    var running_int = try o.builder.intConst(llvm_int_ty, 0);
+                    var running_bits: u16 = 0;
+                    for (struct_type.field_types.get(ip), 0..) |field_ty, field_index| {
+                        if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(mod)) continue;
+
+                        const shift_rhs = try o.builder.intConst(llvm_int_ty, running_bits);
+                        const field_val = try o.lowerValueToInt(llvm_int_ty, (try val.fieldValue(mod, field_index)).toIntern());
+                        const shifted = try o.builder.binConst(.shl, field_val, shift_rhs);
+
+                        running_int = try o.builder.binConst(.xor, running_int, shifted);
+
+                        const ty_bit_size: u16 = @intCast(Type.fromInterned(field_ty).bitSize(mod));
+                        running_bits += ty_bit_size;
+                    }
+                    return running_int;
+                },
+                .vector_type => {},
+                else => unreachable,
+            },
+            .un => |un| {
+                const layout = ty.unionGetLayout(mod);
+                if (layout.payload_size == 0) return o.lowerValue(un.tag);
+
+                const union_obj = mod.typeToUnion(ty).?;
+                const container_layout = union_obj.getLayout(ip);
+
+                assert(container_layout == .@"packed");
+
+                var need_unnamed = false;
+                if (un.tag == .none) {
+                    assert(layout.tag_size == 0);
+                    const union_val = try o.lowerValueToInt(llvm_int_ty, un.val);
+
+                    need_unnamed = true;
+                    return union_val;
+                }
+                const field_index = mod.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?;
+                const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
+                if (!field_ty.hasRuntimeBits(mod)) return o.builder.intConst(llvm_int_ty, 0);
+                return o.lowerValueToInt(llvm_int_ty, un.val);
+            },
+            .simple_value => |simple_value| switch (simple_value) {
+                .false, .true => {},
+                else => unreachable,
+            },
+            .int,
+            .float,
+            .enum_tag,
+            => {},
+            else => unreachable,
+        }
+        const bits = ty.bitSize(mod);
+        const bytes: usize = @intCast(std.mem.alignForward(u64, bits, 8) / 8);
+
+        var stack = std.heap.stackFallback(32, o.gpa);
+        const allocator = stack.get();
+
+        const limbs = try allocator.alloc(
+            std.math.big.Limb,
+            std.mem.alignForward(usize, bytes, @sizeOf(std.math.big.Limb)) /
+                @sizeOf(std.math.big.Limb),
+        );
+        defer allocator.free(limbs);
+        @memset(limbs, 0);
+
+        val.writeToPackedMemory(
+            ty,
+            mod,
+            std.mem.sliceAsBytes(limbs)[0..bytes],
+            0,
+        ) catch unreachable;
+
+        if (builtin.target.cpu.arch.endian() == .little) {
+            if (target.cpu.arch.endian() == .big)
+                std.mem.reverse(u8, std.mem.sliceAsBytes(limbs)[0..bytes]);
+        } else if (target.cpu.arch.endian() == .little) {
+            for (limbs) |*limb| {
+                limb.* = std.mem.nativeToLittle(usize, limb.*);
+            }
+        }
+
+        return o.builder.bigIntConst(llvm_int_ty, .{
+            .limbs = limbs,
+            .positive = true,
+        });
+    }
+
     fn lowerValue(o: *Object, arg_val: InternPool.Index) Error!Builder.Constant {
         const mod = o.module;
         const ip = &mod.intern_pool;
@@ -4022,28 +4140,11 @@ pub const Object = struct {
                     const struct_ty = try o.lowerType(ty);
                     if (struct_type.layout == .@"packed") {
                         comptime assert(Type.packed_struct_layout_version == 2);
-                        var running_int = try o.builder.intConst(struct_ty, 0);
-                        var running_bits: u16 = 0;
-                        for (struct_type.field_types.get(ip), 0..) |field_ty, field_index| {
-                            if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(mod)) continue;
-
-                            const non_int_val =
-                                try o.lowerValue((try val.fieldValue(mod, field_index)).toIntern());
-                            const ty_bit_size: u16 = @intCast(Type.fromInterned(field_ty).bitSize(mod));
-                            const small_int_ty = try o.builder.intType(ty_bit_size);
-                            const small_int_val = try o.builder.castConst(
-                                if (Type.fromInterned(field_ty).isPtrAtRuntime(mod)) .ptrtoint else .bitcast,
-                                non_int_val,
-                                small_int_ty,
-                            );
-                            const shift_rhs = try o.builder.intConst(struct_ty, running_bits);
-                            const extended_int_val =
-                                try o.builder.convConst(.unsigned, small_int_val, struct_ty);
-                            const shifted = try o.builder.binConst(.shl, extended_int_val, shift_rhs);
-                            running_int = try o.builder.binConst(.@"or", running_int, shifted);
-                            running_bits += ty_bit_size;
-                        }
-                        return running_int;
+
+                        const bits = ty.bitSize(mod);
+                        const llvm_int_ty = try o.builder.intType(@intCast(bits));
+
+                        return o.lowerValueToInt(llvm_int_ty, arg_val);
                     }
                     const llvm_len = struct_ty.aggregateLen(&o.builder);
 
@@ -4138,12 +4239,10 @@ pub const Object = struct {
                     const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
                     if (container_layout == .@"packed") {
                         if (!field_ty.hasRuntimeBits(mod)) return o.builder.intConst(union_ty, 0);
-                        const small_int_val = try o.builder.castConst(
-                            if (field_ty.isPtrAtRuntime(mod)) .ptrtoint else .bitcast,
-                            try o.lowerValue(un.val),
-                            try o.builder.intType(@intCast(field_ty.bitSize(mod))),
-                        );
-                        return o.builder.convConst(.unsigned, small_int_val, union_ty);
+                        const bits = ty.bitSize(mod);
+                        const llvm_int_ty = try o.builder.intType(@intCast(bits));
+
+                        return o.lowerValueToInt(llvm_int_ty, arg_val);
                     }
 
                     // Sometimes we must make an unnamed struct because LLVM does
@@ -4171,16 +4270,14 @@ pub const Object = struct {
                     );
                 } else p: {
                     assert(layout.tag_size == 0);
-                    const union_val = try o.lowerValue(un.val);
                     if (container_layout == .@"packed") {
-                        const bitcast_val = try o.builder.castConst(
-                            .bitcast,
-                            union_val,
-                            try o.builder.intType(@intCast(ty.bitSize(mod))),
-                        );
-                        return o.builder.convConst(.unsigned, bitcast_val, union_ty);
+                        const bits = ty.bitSize(mod);
+                        const llvm_int_ty = try o.builder.intType(@intCast(bits));
+
+                        return o.lowerValueToInt(llvm_int_ty, arg_val);
                     }
 
+                    const union_val = try o.lowerValue(un.val);
                     need_unnamed = true;
                     break :p union_val;
                 };
@@ -4316,12 +4413,11 @@ pub const Object = struct {
         const llvm_global = (try o.resolveGlobalAnonDecl(decl_val, llvm_addr_space, alignment)).ptrConst(&o.builder).global;
 
         const llvm_val = try o.builder.convConst(
-            .unneeded,
             llvm_global.toConst(),
             try o.builder.ptrType(llvm_addr_space),
         );
 
-        return o.builder.convConst(.unneeded, llvm_val, try o.lowerType(ptr_ty));
+        return o.builder.convConst(llvm_val, try o.lowerType(ptr_ty));
     }
 
     fn lowerDeclRefValue(o: *Object, decl_index: InternPool.DeclIndex) Allocator.Error!Builder.Constant {
@@ -4359,12 +4455,11 @@ pub const Object = struct {
             (try o.resolveGlobalDecl(decl_index)).ptrConst(&o.builder).global;
 
         const llvm_val = try o.builder.convConst(
-            .unneeded,
             llvm_global.toConst(),
             try o.builder.ptrType(toLlvmAddressSpace(decl.@"addrspace", mod.getTarget())),
         );
 
-        return o.builder.convConst(.unneeded, llvm_val, try o.lowerType(ptr_ty));
+        return o.builder.convConst(llvm_val, try o.lowerType(ptr_ty));
     }
 
     fn lowerPtrToVoid(o: *Object, ptr_ty: Type) Allocator.Error!Builder.Constant {
@@ -4750,7 +4845,6 @@ pub const FuncGen = struct {
         variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);
         variable_index.setAlignment(ty.abiAlignment(mod).toLlvm(), &o.builder);
         return o.builder.convConst(
-            .unneeded,
             variable_index.toConst(&o.builder),
             try o.builder.ptrType(toLlvmAddressSpace(.generic, target)),
         );
@@ -10413,9 +10507,9 @@ pub const FuncGen = struct {
 
         const anded = if (workaround_explicit_mask and payload_llvm_ty != load_llvm_ty) blk: {
             // this is rendundant with llvm.trunc. But without it, llvm17 emits invalid code for powerpc.
-            var mask_val = try o.builder.intConst(payload_llvm_ty, -1);
-            mask_val = try o.builder.castConst(.zext, mask_val, load_llvm_ty);
-            break :blk try fg.wip.bin(.@"and", shifted, mask_val.toValue(), "");
+            const mask_val = try o.builder.intValue(payload_llvm_ty, -1);
+            const zext_mask_val = try fg.wip.cast(.zext, mask_val, load_llvm_ty, "");
+            break :blk try fg.wip.bin(.@"and", shifted, zext_mask_val, "");
         } else shifted;
 
         return fg.wip.conv(.unneeded, anded, payload_llvm_ty, "");
@@ -10563,14 +10657,23 @@ pub const FuncGen = struct {
             else
                 try self.wip.cast(.bitcast, elem, value_bits_type, "");
 
-            var mask_val = try o.builder.intConst(value_bits_type, -1);
-            mask_val = try o.builder.castConst(.zext, mask_val, containing_int_ty);
-            mask_val = try o.builder.binConst(.shl, mask_val, shift_amt);
-            mask_val =
-                try o.builder.binConst(.xor, mask_val, try o.builder.intConst(containing_int_ty, -1));
+            const mask_val = blk: {
+                const zext = try self.wip.cast(
+                    .zext,
+                    try o.builder.intValue(value_bits_type, -1),
+                    containing_int_ty,
+                    "",
+                );
+                const shl = try self.wip.bin(.shl, zext, shift_amt.toValue(), "");
+                break :blk try self.wip.bin(
+                    .xor,
+                    shl,
+                    try o.builder.intValue(containing_int_ty, -1),
+                    "",
+                );
+            };
 
-            const anded_containing_int =
-                try self.wip.bin(.@"and", containing_int, mask_val.toValue(), "");
+            const anded_containing_int = try self.wip.bin(.@"and", containing_int, mask_val, "");
             const extended_value = try self.wip.cast(.zext, value_bits, containing_int_ty, "");
             const shifted_value = try self.wip.bin(.shl, extended_value, shift_amt.toValue(), "");
             const ored_value = try self.wip.bin(.@"or", shifted_value, anded_containing_int, "");