aboutsummaryrefslogtreecommitdiff
path: root/src/stage1/codegen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/stage1/codegen.cpp')
-rw-r--r--src/stage1/codegen.cpp20
1 files changed, 20 insertions, 0 deletions
diff --git a/src/stage1/codegen.cpp b/src/stage1/codegen.cpp
index 8f74536665..c034a79cea 100644
--- a/src/stage1/codegen.cpp
+++ b/src/stage1/codegen.cpp
@@ -5460,6 +5460,8 @@ static LLVMValueRef ir_render_reduce(CodeGen *g, IrExecutableGen *executable, Ir
assert(value_type->id == ZigTypeIdVector);
ZigType *scalar_type = value_type->data.vector.elem_type;
+ ZigLLVMSetFastMath(g->builder, ir_want_fast_math(g, &instruction->base));
+
LLVMValueRef result_val;
switch (instruction->op) {
case ReduceOp_and:
@@ -5490,6 +5492,24 @@ static LLVMValueRef ir_render_reduce(CodeGen *g, IrExecutableGen *executable, Ir
result_val = ZigLLVMBuildFPMaxReduce(g->builder, value);
} else zig_unreachable();
} break;
+ case ReduceOp_add: {
+ if (scalar_type->id == ZigTypeIdInt) {
+ result_val = ZigLLVMBuildAddReduce(g->builder, value);
+ } else if (scalar_type->id == ZigTypeIdFloat) {
+ LLVMValueRef neutral_value = LLVMConstReal(
+ get_llvm_type(g, scalar_type), -0.0);
+ result_val = ZigLLVMBuildFPAddReduce(g->builder, neutral_value, value);
+ } else zig_unreachable();
+ } break;
+ case ReduceOp_mul: {
+ if (scalar_type->id == ZigTypeIdInt) {
+ result_val = ZigLLVMBuildMulReduce(g->builder, value);
+ } else if (scalar_type->id == ZigTypeIdFloat) {
+ LLVMValueRef neutral_value = LLVMConstReal(
+ get_llvm_type(g, scalar_type), 1.0);
+ result_val = ZigLLVMBuildFPMulReduce(g->builder, neutral_value, value);
+ } else zig_unreachable();
+ } break;
default:
zig_unreachable();
}