saturating arithmetic builtins: add, sub, mul, shl (#9619)

- adds 1 simple behavior tests for each
  which does integer and vector ops at
  runtime and comptime
- adds bigint_*_sat() methods for each

- use CreateIntrinsic() which accepts a
  variable number of arguments to pass
  the scale parameter

* update langref
- added case to test/compile_errors.zig given floats

- explain upstream bug in llvm.smul.fix.sat and link to #9643 in langref and commented out test cases

* sat-arithmetic: skip mul tests if arch == .wasm32 because ci is erroring with 'LLVM ERROR: Unable to expand fixed point multiplication' when compiling for wasm32
This commit is contained in:
travisstaloch
2021-09-01 11:17:45 -07:00
committed by GitHub
parent 4f0aa7d639
commit 21a5769afe
17 changed files with 613 additions and 3 deletions

View File

@@ -3335,6 +3335,46 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, Stage1Air *executable,
} else {
zig_unreachable();
}
case IrBinOpSatAdd:
if (scalar_type->id == ZigTypeIdInt) {
if (scalar_type->data.integral.is_signed) {
return ZigLLVMBuildSAddSat(g->builder, op1_value, op2_value, "");
} else {
return ZigLLVMBuildUAddSat(g->builder, op1_value, op2_value, "");
}
} else {
zig_unreachable();
}
case IrBinOpSatSub:
if (scalar_type->id == ZigTypeIdInt) {
if (scalar_type->data.integral.is_signed) {
return ZigLLVMBuildSSubSat(g->builder, op1_value, op2_value, "");
} else {
return ZigLLVMBuildUSubSat(g->builder, op1_value, op2_value, "");
}
} else {
zig_unreachable();
}
case IrBinOpSatMul:
if (scalar_type->id == ZigTypeIdInt) {
if (scalar_type->data.integral.is_signed) {
return ZigLLVMBuildSMulFixSat(g->builder, op1_value, op2_value, "");
} else {
return ZigLLVMBuildUMulFixSat(g->builder, op1_value, op2_value, "");
}
} else {
zig_unreachable();
}
case IrBinOpSatShl:
if (scalar_type->id == ZigTypeIdInt) {
if (scalar_type->data.integral.is_signed) {
return ZigLLVMBuildSShlSat(g->builder, op1_value, op2_value, "");
} else {
return ZigLLVMBuildUShlSat(g->builder, op1_value, op2_value, "");
}
} else {
zig_unreachable();
}
}
zig_unreachable();
}
@@ -9096,6 +9136,10 @@ static void define_builtin_fns(CodeGen *g) {
create_builtin_fn(g, BuiltinFnIdReduce, "reduce", 2);
create_builtin_fn(g, BuiltinFnIdMaximum, "maximum", 2);
create_builtin_fn(g, BuiltinFnIdMinimum, "minimum", 2);
create_builtin_fn(g, BuiltinFnIdSatAdd, "addWithSaturation", 2);
create_builtin_fn(g, BuiltinFnIdSatSub, "subWithSaturation", 2);
create_builtin_fn(g, BuiltinFnIdSatMul, "mulWithSaturation", 2);
create_builtin_fn(g, BuiltinFnIdSatShl, "shlWithSaturation", 2);
}
static const char *bool_to_str(bool b) {