aboutsummaryrefslogtreecommitdiff
path: root/src/llvm_backend_proc.cpp
diff options
context:
space:
mode:
authorLaytan <laytanlaats@hotmail.com>2024-07-16 22:30:06 +0200
committerGitHub <noreply@github.com>2024-07-16 22:30:06 +0200
commitcb16d2ddaf5d70c39684c6ef2daa66f40619c1c6 (patch)
treef6b29f25fd09d648e9772a2e5dfa0ea40c6f2ae7 /src/llvm_backend_proc.cpp
parent0d881e1561d62065a6c702c3eabadc253a8f2bc6 (diff)
parenta6d1a2e46cb38df2583ba1d14be2516f16bba655 (diff)
Merge pull request #3934 from laytan/fix-saturating-intrinsics
fix `add_sat` and `sub_sat` intrinsics
Diffstat (limited to 'src/llvm_backend_proc.cpp')
-rw-r--r--src/llvm_backend_proc.cpp39
1 files changed, 33 insertions, 6 deletions
diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp
index bdc381bc4..2f736ff6c 100644
--- a/src/llvm_backend_proc.cpp
+++ b/src/llvm_backend_proc.cpp
@@ -2236,8 +2236,6 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu
case BuiltinProc_overflow_add:
case BuiltinProc_overflow_sub:
case BuiltinProc_overflow_mul:
- case BuiltinProc_add_sat:
- case BuiltinProc_sub_sat:
{
Type *main_type = tv.type;
Type *type = main_type;
@@ -2256,16 +2254,12 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu
case BuiltinProc_overflow_add: name = "llvm.uadd.with.overflow"; break;
case BuiltinProc_overflow_sub: name = "llvm.usub.with.overflow"; break;
case BuiltinProc_overflow_mul: name = "llvm.umul.with.overflow"; break;
- case BuiltinProc_add_sat: name = "llvm.uadd.sat"; break;
- case BuiltinProc_sub_sat: name = "llvm.usub.sat"; break;
}
} else {
switch (id) {
case BuiltinProc_overflow_add: name = "llvm.sadd.with.overflow"; break;
case BuiltinProc_overflow_sub: name = "llvm.ssub.with.overflow"; break;
case BuiltinProc_overflow_mul: name = "llvm.smul.with.overflow"; break;
- case BuiltinProc_add_sat: name = "llvm.sadd.sat"; break;
- case BuiltinProc_sub_sat: name = "llvm.ssub.sat"; break;
}
}
LLVMTypeRef types[1] = {lb_type(p->module, type)};
@@ -2291,6 +2285,39 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu
return res;
}
+ case BuiltinProc_add_sat:
+ case BuiltinProc_sub_sat:
+ {
+ Type *main_type = tv.type;
+ Type *type = main_type;
+
+ lbValue x = lb_build_expr(p, ce->args[0]);
+ lbValue y = lb_build_expr(p, ce->args[1]);
+ x = lb_emit_conv(p, x, type);
+ y = lb_emit_conv(p, y, type);
+
+ char const *name = nullptr;
+ if (is_type_unsigned(type)) {
+ switch (id) {
+ case BuiltinProc_add_sat: name = "llvm.uadd.sat"; break;
+ case BuiltinProc_sub_sat: name = "llvm.usub.sat"; break;
+ }
+ } else {
+ switch (id) {
+ case BuiltinProc_add_sat: name = "llvm.sadd.sat"; break;
+ case BuiltinProc_sub_sat: name = "llvm.ssub.sat"; break;
+ }
+ }
+ LLVMTypeRef types[1] = {lb_type(p->module, type)};
+
+ LLVMValueRef args[2] = { x.value, y.value };
+
+ lbValue res = {};
+ res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
+ res.type = type;
+ return res;
+ }
+
case BuiltinProc_sqrt:
{
Type *type = tv.type;