aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <gingerBill@users.noreply.github.com>2025-08-10 17:53:07 +0100
committergingerBill <gingerBill@users.noreply.github.com>2025-08-10 17:53:07 +0100
commit4cbcb3ace7c0d066e8d5105e4b3582300f93d533 (patch)
treed72f8a02240728364cd86e5a8148b26e3c79f40a /src
parentda76c743e9b7c88f2f15bbee1dba3b2ab6ebc0b0 (diff)
Add shortcut for `unsigned_x/power_of_two` -> `unsigned_x >> log2(power_of_two)`
Diffstat (limited to 'src')
-rw-r--r--src/common.cpp7
-rw-r--r--src/llvm_backend_expr.cpp11
2 files changed, 18 insertions, 0 deletions
diff --git a/src/common.cpp b/src/common.cpp
index 53848cacf..5b007bf2c 100644
--- a/src/common.cpp
+++ b/src/common.cpp
@@ -80,6 +80,13 @@ gb_internal gb_inline bool is_power_of_two(i64 x) {
return !(x & (x-1));
}
+gb_internal gb_inline bool is_power_of_two_u64(u64 x) {
+ if (x == 0) {
+ return false;
+ }
+ return !(x & (x-1));
+}
+
gb_internal int isize_cmp(isize x, isize y) {
if (x < y) {
return -1;
diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp
index 13c6082fb..f922c6359 100644
--- a/src/llvm_backend_expr.cpp
+++ b/src/llvm_backend_expr.cpp
@@ -1153,6 +1153,17 @@ gb_internal LLVMValueRef lb_integer_division(lbProcedure *p, LLVMValueRef lhs, L
return zero;
}
} else {
+ if (!is_signed && lb_sizeof(type) <= 8) {
+ u64 v = cast(u64)LLVMConstIntGetZExtValue(rhs);
+ if (v == 1) {
+ return lhs;
+ } else if (is_power_of_two_u64(v)) {
+ u64 n = floor_log2(v);
+ LLVMValueRef bits = LLVMConstInt(type, n, false);
+ return LLVMBuildLShr(p->builder, lhs, bits, "");
+ }
+ }
+
return call(p->builder, lhs, rhs, "");
}
}