Commit 6577f52614

Jacob Young <jacobly0@users.noreply.github.com>
2023-08-07 11:24:14
llvm: convert vector reduction intrinsics
Scratch that thing I said about one pass. :)
1 parent e1efd4d
src/codegen/llvm/bindings.zig
@@ -993,39 +993,6 @@ pub const Builder = opaque {
     pub const buildShuffleVector = LLVMBuildShuffleVector;
     extern fn LLVMBuildShuffleVector(*Builder, V1: *Value, V2: *Value, Mask: *Value, Name: [*:0]const u8) *Value;
 
-    pub const buildAndReduce = ZigLLVMBuildAndReduce;
-    extern fn ZigLLVMBuildAndReduce(B: *Builder, Val: *Value) *Value;
-
-    pub const buildOrReduce = ZigLLVMBuildOrReduce;
-    extern fn ZigLLVMBuildOrReduce(B: *Builder, Val: *Value) *Value;
-
-    pub const buildXorReduce = ZigLLVMBuildXorReduce;
-    extern fn ZigLLVMBuildXorReduce(B: *Builder, Val: *Value) *Value;
-
-    pub const buildIntMaxReduce = ZigLLVMBuildIntMaxReduce;
-    extern fn ZigLLVMBuildIntMaxReduce(B: *Builder, Val: *Value, is_signed: bool) *Value;
-
-    pub const buildIntMinReduce = ZigLLVMBuildIntMinReduce;
-    extern fn ZigLLVMBuildIntMinReduce(B: *Builder, Val: *Value, is_signed: bool) *Value;
-
-    pub const buildFPMaxReduce = ZigLLVMBuildFPMaxReduce;
-    extern fn ZigLLVMBuildFPMaxReduce(B: *Builder, Val: *Value) *Value;
-
-    pub const buildFPMinReduce = ZigLLVMBuildFPMinReduce;
-    extern fn ZigLLVMBuildFPMinReduce(B: *Builder, Val: *Value) *Value;
-
-    pub const buildAddReduce = ZigLLVMBuildAddReduce;
-    extern fn ZigLLVMBuildAddReduce(B: *Builder, Val: *Value) *Value;
-
-    pub const buildMulReduce = ZigLLVMBuildMulReduce;
-    extern fn ZigLLVMBuildMulReduce(B: *Builder, Val: *Value) *Value;
-
-    pub const buildFPAddReduce = ZigLLVMBuildFPAddReduce;
-    extern fn ZigLLVMBuildFPAddReduce(B: *Builder, Acc: *Value, Val: *Value) *Value;
-
-    pub const buildFPMulReduce = ZigLLVMBuildFPMulReduce;
-    extern fn ZigLLVMBuildFPMulReduce(B: *Builder, Acc: *Value, Val: *Value) *Value;
-
     pub const setFastMath = ZigLLVMSetFastMath;
     extern fn ZigLLVMSetFastMath(B: *Builder, on_state: bool) void;
 
src/codegen/llvm/Builder.zig
@@ -2472,12 +2472,13 @@ pub const Intrinsic = enum {
 
             const Kind = union(enum) {
                 type: Type,
-                change_scalar: struct {
+                overloaded,
+                matches: u8,
+                matches_scalar: u8,
+                matches_changed_scalar: struct {
                     index: u8,
                     scalar: Type,
                 },
-                overloaded,
-                matches: u8,
             };
         };
     };
@@ -2921,7 +2922,7 @@ pub const Intrinsic = enum {
             .ret_len = 2,
             .params = &.{
                 .{ .kind = .overloaded },
-                .{ .kind = .{ .change_scalar = .{ .index = 0, .scalar = .i1 } } },
+                .{ .kind = .{ .matches_changed_scalar = .{ .index = 0, .scalar = .i1 } } },
                 .{ .kind = .{ .matches = 0 } },
                 .{ .kind = .{ .matches = 0 } },
             },
@@ -2931,7 +2932,7 @@ pub const Intrinsic = enum {
             .ret_len = 2,
             .params = &.{
                 .{ .kind = .overloaded },
-                .{ .kind = .{ .change_scalar = .{ .index = 0, .scalar = .i1 } } },
+                .{ .kind = .{ .matches_changed_scalar = .{ .index = 0, .scalar = .i1 } } },
                 .{ .kind = .{ .matches = 0 } },
                 .{ .kind = .{ .matches = 0 } },
             },
@@ -2941,7 +2942,7 @@ pub const Intrinsic = enum {
             .ret_len = 2,
             .params = &.{
                 .{ .kind = .overloaded },
-                .{ .kind = .{ .change_scalar = .{ .index = 0, .scalar = .i1 } } },
+                .{ .kind = .{ .matches_changed_scalar = .{ .index = 0, .scalar = .i1 } } },
                 .{ .kind = .{ .matches = 0 } },
                 .{ .kind = .{ .matches = 0 } },
             },
@@ -2951,7 +2952,7 @@ pub const Intrinsic = enum {
             .ret_len = 2,
             .params = &.{
                 .{ .kind = .overloaded },
-                .{ .kind = .{ .change_scalar = .{ .index = 0, .scalar = .i1 } } },
+                .{ .kind = .{ .matches_changed_scalar = .{ .index = 0, .scalar = .i1 } } },
                 .{ .kind = .{ .matches = 0 } },
                 .{ .kind = .{ .matches = 0 } },
             },
@@ -2961,7 +2962,7 @@ pub const Intrinsic = enum {
             .ret_len = 2,
             .params = &.{
                 .{ .kind = .overloaded },
-                .{ .kind = .{ .change_scalar = .{ .index = 0, .scalar = .i1 } } },
+                .{ .kind = .{ .matches_changed_scalar = .{ .index = 0, .scalar = .i1 } } },
                 .{ .kind = .{ .matches = 0 } },
                 .{ .kind = .{ .matches = 0 } },
             },
@@ -2971,7 +2972,7 @@ pub const Intrinsic = enum {
             .ret_len = 2,
             .params = &.{
                 .{ .kind = .overloaded },
-                .{ .kind = .{ .change_scalar = .{ .index = 0, .scalar = .i1 } } },
+                .{ .kind = .{ .matches_changed_scalar = .{ .index = 0, .scalar = .i1 } } },
                 .{ .kind = .{ .matches = 0 } },
                 .{ .kind = .{ .matches = 0 } },
             },
@@ -3114,6 +3115,148 @@ pub const Intrinsic = enum {
             .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
         },
 
+        .@"vector.reduce.add" = .{
+            .ret_len = 1,
+            .params = &.{
+                .{ .kind = .{ .matches_scalar = 1 } },
+                .{ .kind = .overloaded },
+            },
+            .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
+        },
+        .@"vector.reduce.fadd" = .{
+            .ret_len = 1,
+            .params = &.{
+                .{ .kind = .{ .matches_scalar = 2 } },
+                .{ .kind = .{ .matches_scalar = 2 } },
+                .{ .kind = .overloaded },
+            },
+            .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
+        },
+        .@"vector.reduce.mul" = .{
+            .ret_len = 1,
+            .params = &.{
+                .{ .kind = .{ .matches_scalar = 1 } },
+                .{ .kind = .overloaded },
+            },
+            .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
+        },
+        .@"vector.reduce.fmul" = .{
+            .ret_len = 1,
+            .params = &.{
+                .{ .kind = .{ .matches_scalar = 2 } },
+                .{ .kind = .{ .matches_scalar = 2 } },
+                .{ .kind = .overloaded },
+            },
+            .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
+        },
+        .@"vector.reduce.and" = .{
+            .ret_len = 1,
+            .params = &.{
+                .{ .kind = .{ .matches_scalar = 1 } },
+                .{ .kind = .overloaded },
+            },
+            .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
+        },
+        .@"vector.reduce.or" = .{
+            .ret_len = 1,
+            .params = &.{
+                .{ .kind = .{ .matches_scalar = 1 } },
+                .{ .kind = .overloaded },
+            },
+            .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
+        },
+        .@"vector.reduce.xor" = .{
+            .ret_len = 1,
+            .params = &.{
+                .{ .kind = .{ .matches_scalar = 1 } },
+                .{ .kind = .overloaded },
+            },
+            .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
+        },
+        .@"vector.reduce.smax" = .{
+            .ret_len = 1,
+            .params = &.{
+                .{ .kind = .{ .matches_scalar = 1 } },
+                .{ .kind = .overloaded },
+            },
+            .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
+        },
+        .@"vector.reduce.smin" = .{
+            .ret_len = 1,
+            .params = &.{
+                .{ .kind = .{ .matches_scalar = 1 } },
+                .{ .kind = .overloaded },
+            },
+            .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
+        },
+        .@"vector.reduce.umax" = .{
+            .ret_len = 1,
+            .params = &.{
+                .{ .kind = .{ .matches_scalar = 1 } },
+                .{ .kind = .overloaded },
+            },
+            .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
+        },
+        .@"vector.reduce.umin" = .{
+            .ret_len = 1,
+            .params = &.{
+                .{ .kind = .{ .matches_scalar = 1 } },
+                .{ .kind = .overloaded },
+            },
+            .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
+        },
+        .@"vector.reduce.fmax" = .{
+            .ret_len = 1,
+            .params = &.{
+                .{ .kind = .{ .matches_scalar = 1 } },
+                .{ .kind = .overloaded },
+            },
+            .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
+        },
+        .@"vector.reduce.fmin" = .{
+            .ret_len = 1,
+            .params = &.{
+                .{ .kind = .{ .matches_scalar = 1 } },
+                .{ .kind = .overloaded },
+            },
+            .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
+        },
+        .@"vector.reduce.fmaximum" = .{
+            .ret_len = 1,
+            .params = &.{
+                .{ .kind = .{ .matches_scalar = 1 } },
+                .{ .kind = .overloaded },
+            },
+            .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
+        },
+        .@"vector.reduce.fminimum" = .{
+            .ret_len = 1,
+            .params = &.{
+                .{ .kind = .{ .matches_scalar = 1 } },
+                .{ .kind = .overloaded },
+            },
+            .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
+        },
+        .@"vector.insert" = .{
+            .ret_len = 1,
+            .params = &.{
+                .{ .kind = .overloaded },
+                .{ .kind = .{ .matches = 0 } },
+                .{ .kind = .overloaded },
+                .{ .kind = .{ .type = .i64 } },
+            },
+            .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
+        },
+        .@"vector.extract" = .{
+            .ret_len = 1,
+            .params = &.{
+                .{ .kind = .overloaded },
+                .{ .kind = .overloaded },
+                .{ .kind = .{ .type = .i64 } },
+            },
+            .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
+        },
+
         .trap = .{
             .ret_len = 0,
             .params = &.{},
@@ -7742,18 +7885,11 @@ pub fn getIntrinsic(
     for (0.., param_types, signature.params) |param_index, *param_type, signature_param| {
         switch (signature_param.kind) {
             .type => |ty| param_type.* = ty,
-            .change_scalar => |info| {
-                assert(info.index < param_index);
-                param_type.* = try param_types[info.index].changeScalar(info.scalar, self);
-            },
             .overloaded => {
                 param_type.* = overload[overload_index];
                 overload_index += 1;
             },
-            .matches => |index| {
-                assert(index < param_index);
-                param_type.* = param_types[index];
-            },
+            .matches, .matches_scalar, .matches_changed_scalar => {},
         }
         function_attributes[
             if (param_index < signature.ret_len)
@@ -7763,6 +7899,15 @@ pub fn getIntrinsic(
         ] = try attributes.get(signature_param.attrs);
     }
     assert(overload_index == overload.len);
+    for (param_types, signature.params) |*param_type, signature_param| {
+        param_type.* = switch (signature_param.kind) {
+            .type, .overloaded => continue,
+            .matches => |param_index| param_types[param_index],
+            .matches_scalar => |param_index| param_types[param_index].scalarType(self),
+            .matches_changed_scalar => |info| try param_types[info.index]
+                .changeScalar(info.scalar, self),
+        };
+    }
 
     const function_index =
         try self.addFunction(try self.fnType(switch (signature.ret_len) {
src/codegen/llvm.zig
@@ -7464,18 +7464,16 @@ pub const FuncGen = struct {
         const llvm_inst_ty = try o.lowerType(inst_ty);
         const results = try fg.wip.callIntrinsic(intrinsic, &.{llvm_inst_ty}, &.{ lhs, rhs }, "");
 
-        const overflow_bit = try fg.wip.extractValue(results, &.{1}, "");
-        const scalar_overflow_bit = if (llvm_inst_ty.isVector(&o.builder))
-            (try fg.wip.unimplemented(.i1, "")).finish(
-                fg.builder.buildOrReduce(overflow_bit.toLlvm(&fg.wip)),
-                &fg.wip,
-            )
+        const overflow_bits = try fg.wip.extractValue(results, &.{1}, "");
+        const overflow_bits_ty = overflow_bits.typeOfWip(&fg.wip);
+        const overflow_bit = if (overflow_bits_ty.isVector(&o.builder))
+            try fg.wip.callIntrinsic(.@"vector.reduce.or", &.{overflow_bits_ty}, &.{overflow_bits}, "")
         else
-            overflow_bit;
+            overflow_bits;
 
         const fail_block = try fg.wip.block(1, "OverflowFail");
         const ok_block = try fg.wip.block(1, "OverflowOk");
-        _ = try fg.wip.brCond(scalar_overflow_bit, fail_block, ok_block);
+        _ = try fg.wip.brCond(overflow_bit, fail_block, ok_block);
 
         fg.wip.cursor = .{ .block = fail_block };
         try fg.buildSimplePanic(.integer_overflow);
@@ -9643,72 +9641,53 @@ pub const FuncGen = struct {
         const reduce = self.air.instructions.items(.data)[inst].reduce;
         const operand = try self.resolveInst(reduce.operand);
         const operand_ty = self.typeOf(reduce.operand);
+        const llvm_operand_ty = try o.lowerType(operand_ty);
         const scalar_ty = self.typeOfIndex(inst);
         const llvm_scalar_ty = try o.lowerType(scalar_ty);
 
         switch (reduce.operation) {
-            .And => return (try self.wip.unimplemented(llvm_scalar_ty, ""))
-                .finish(self.builder.buildAndReduce(operand.toLlvm(&self.wip)), &self.wip),
-            .Or => return (try self.wip.unimplemented(llvm_scalar_ty, ""))
-                .finish(self.builder.buildOrReduce(operand.toLlvm(&self.wip)), &self.wip),
-            .Xor => return (try self.wip.unimplemented(llvm_scalar_ty, ""))
-                .finish(self.builder.buildXorReduce(operand.toLlvm(&self.wip)), &self.wip),
-            .Min => switch (scalar_ty.zigTypeTag(mod)) {
-                .Int => return (try self.wip.unimplemented(llvm_scalar_ty, "")).finish(
-                    self.builder.buildIntMinReduce(
-                        operand.toLlvm(&self.wip),
-                        scalar_ty.isSignedInt(mod),
-                    ),
-                    &self.wip,
-                ),
-                .Float => if (intrinsicsAllowed(scalar_ty, target)) {
-                    return (try self.wip.unimplemented(llvm_scalar_ty, ""))
-                        .finish(self.builder.buildFPMinReduce(operand.toLlvm(&self.wip)), &self.wip);
-                },
+            .And, .Or, .Xor => return self.wip.callIntrinsic(switch (reduce.operation) {
+                .And => .@"vector.reduce.and",
+                .Or => .@"vector.reduce.or",
+                .Xor => .@"vector.reduce.xor",
                 else => unreachable,
-            },
-            .Max => switch (scalar_ty.zigTypeTag(mod)) {
-                .Int => return (try self.wip.unimplemented(llvm_scalar_ty, "")).finish(
-                    self.builder.buildIntMaxReduce(
-                        operand.toLlvm(&self.wip),
-                        scalar_ty.isSignedInt(mod),
-                    ),
-                    &self.wip,
-                ),
-                .Float => if (intrinsicsAllowed(scalar_ty, target)) {
-                    return (try self.wip.unimplemented(llvm_scalar_ty, ""))
-                        .finish(self.builder.buildFPMaxReduce(operand.toLlvm(&self.wip)), &self.wip);
-                },
-                else => unreachable,
-            },
-            .Add => switch (scalar_ty.zigTypeTag(mod)) {
-                .Int => return (try self.wip.unimplemented(llvm_scalar_ty, ""))
-                    .finish(self.builder.buildAddReduce(operand.toLlvm(&self.wip)), &self.wip),
-                .Float => if (intrinsicsAllowed(scalar_ty, target)) {
-                    const neutral_value = try o.builder.fpConst(llvm_scalar_ty, -0.0);
-                    return (try self.wip.unimplemented(llvm_scalar_ty, "")).finish(
-                        self.builder.buildFPAddReduce(
-                            neutral_value.toLlvm(&o.builder),
-                            operand.toLlvm(&self.wip),
-                        ),
-                        &self.wip,
-                    );
-                },
+            }, &.{llvm_operand_ty}, &.{operand}, ""),
+            .Min, .Max => switch (scalar_ty.zigTypeTag(mod)) {
+                .Int => return self.wip.callIntrinsic(switch (reduce.operation) {
+                    .Min => if (scalar_ty.isSignedInt(mod))
+                        .@"vector.reduce.smin"
+                    else
+                        .@"vector.reduce.umin",
+                    .Max => if (scalar_ty.isSignedInt(mod))
+                        .@"vector.reduce.smax"
+                    else
+                        .@"vector.reduce.umax",
+                    else => unreachable,
+                }, &.{llvm_operand_ty}, &.{operand}, ""),
+                .Float => if (intrinsicsAllowed(scalar_ty, target))
+                    return self.wip.callIntrinsic(switch (reduce.operation) {
+                        .Min => .@"vector.reduce.fmin",
+                        .Max => .@"vector.reduce.fmax",
+                        else => unreachable,
+                    }, &.{llvm_operand_ty}, &.{operand}, ""),
                 else => unreachable,
             },
-            .Mul => switch (scalar_ty.zigTypeTag(mod)) {
-                .Int => return (try self.wip.unimplemented(llvm_scalar_ty, ""))
-                    .finish(self.builder.buildMulReduce(operand.toLlvm(&self.wip)), &self.wip),
-                .Float => if (intrinsicsAllowed(scalar_ty, target)) {
-                    const neutral_value = try o.builder.fpConst(llvm_scalar_ty, 1.0);
-                    return (try self.wip.unimplemented(llvm_scalar_ty, "")).finish(
-                        self.builder.buildFPMulReduce(
-                            neutral_value.toLlvm(&o.builder),
-                            operand.toLlvm(&self.wip),
-                        ),
-                        &self.wip,
-                    );
-                },
+            .Add, .Mul => switch (scalar_ty.zigTypeTag(mod)) {
+                .Int => return self.wip.callIntrinsic(switch (reduce.operation) {
+                    .Add => .@"vector.reduce.add",
+                    .Mul => .@"vector.reduce.mul",
+                    else => unreachable,
+                }, &.{llvm_operand_ty}, &.{operand}, ""),
+                .Float => if (intrinsicsAllowed(scalar_ty, target))
+                    return self.wip.callIntrinsic(switch (reduce.operation) {
+                        .Add => .@"vector.reduce.fadd",
+                        .Mul => .@"vector.reduce.fmul",
+                        else => unreachable,
+                    }, &.{llvm_operand_ty}, &.{ switch (reduce.operation) {
+                        .Add => try o.builder.fpValue(llvm_scalar_ty, -0.0),
+                        .Mul => try o.builder.fpValue(llvm_scalar_ty, 1.0),
+                        else => unreachable,
+                    }, operand }, ""),
                 else => unreachable,
             },
         }
src/zig_llvm.cpp
@@ -1134,50 +1134,6 @@ bool ZigLLDLinkWasm(int argc, const char **argv, bool can_exit_early, bool disab
     return lld::wasm::link(args, llvm::outs(), llvm::errs(), can_exit_early, disable_output);
 }
 
-LLVMValueRef ZigLLVMBuildAndReduce(LLVMBuilderRef B, LLVMValueRef Val) {
-    return wrap(unwrap(B)->CreateAndReduce(unwrap(Val)));
-}
-
-LLVMValueRef ZigLLVMBuildOrReduce(LLVMBuilderRef B, LLVMValueRef Val) {
-    return wrap(unwrap(B)->CreateOrReduce(unwrap(Val)));
-}
-
-LLVMValueRef ZigLLVMBuildXorReduce(LLVMBuilderRef B, LLVMValueRef Val) {
-    return wrap(unwrap(B)->CreateXorReduce(unwrap(Val)));
-}
-
-LLVMValueRef ZigLLVMBuildIntMaxReduce(LLVMBuilderRef B, LLVMValueRef Val, bool is_signed) {
-    return wrap(unwrap(B)->CreateIntMaxReduce(unwrap(Val), is_signed));
-}
-
-LLVMValueRef ZigLLVMBuildIntMinReduce(LLVMBuilderRef B, LLVMValueRef Val, bool is_signed) {
-    return wrap(unwrap(B)->CreateIntMinReduce(unwrap(Val), is_signed));
-}
-
-LLVMValueRef ZigLLVMBuildFPMaxReduce(LLVMBuilderRef B, LLVMValueRef Val) {
-    return wrap(unwrap(B)->CreateFPMaxReduce(unwrap(Val)));
-}
-
-LLVMValueRef ZigLLVMBuildFPMinReduce(LLVMBuilderRef B, LLVMValueRef Val) {
-    return wrap(unwrap(B)->CreateFPMinReduce(unwrap(Val)));
-}
-
-LLVMValueRef ZigLLVMBuildAddReduce(LLVMBuilderRef B, LLVMValueRef Val) {
-    return wrap(unwrap(B)->CreateAddReduce(unwrap(Val)));
-}
-
-LLVMValueRef ZigLLVMBuildMulReduce(LLVMBuilderRef B, LLVMValueRef Val) {
-    return wrap(unwrap(B)->CreateMulReduce(unwrap(Val)));
-}
-
-LLVMValueRef ZigLLVMBuildFPAddReduce(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Val) {
-    return wrap(unwrap(B)->CreateFAddReduce(unwrap(Acc), unwrap(Val)));
-}
-
-LLVMValueRef ZigLLVMBuildFPMulReduce(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Val) {
-    return wrap(unwrap(B)->CreateFMulReduce(unwrap(Acc), unwrap(Val)));
-}
-
 void ZigLLVMTakeName(LLVMValueRef new_owner, LLVMValueRef victim) {
     unwrap(new_owner)->takeName(unwrap(victim));
 }
src/zig_llvm.h
@@ -497,18 +497,6 @@ enum ZigLLVM_ObjectFormatType {
     ZigLLVM_XCOFF,
 };
 
-ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildAndReduce(LLVMBuilderRef B, LLVMValueRef Val);
-ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildOrReduce(LLVMBuilderRef B, LLVMValueRef Val);
-ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildXorReduce(LLVMBuilderRef B, LLVMValueRef Val);
-ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildIntMaxReduce(LLVMBuilderRef B, LLVMValueRef Val, bool is_signed);
-ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildIntMinReduce(LLVMBuilderRef B, LLVMValueRef Val, bool is_signed);
-ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildFPMaxReduce(LLVMBuilderRef B, LLVMValueRef Val);
-ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildFPMinReduce(LLVMBuilderRef B, LLVMValueRef Val);
-ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildAddReduce(LLVMBuilderRef B, LLVMValueRef Val);
-ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildMulReduce(LLVMBuilderRef B, LLVMValueRef Val);
-ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildFPAddReduce(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Val);
-ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildFPMulReduce(LLVMBuilderRef B, LLVMValueRef Acc, LLVMValueRef Val);
-
 ZIG_EXTERN_C void ZigLLVMTakeName(LLVMValueRef new_owner, LLVMValueRef victim);
 
 #define ZigLLVM_DIFlags_Zero 0U