authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2021-11-15 19:09:20+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-11-16 16:35:56-05:00
log952d865bd231834adad30905c469edc5a46d000a
tree49fe04fcec82ad893fc012bfc02624dd086864fb
parent9c1c1d478d3f5a541c142bb32b22a77c2f500953

stage1: Fix caching of LLVM builtin fns

The cache entry must take into account the fact some functions operate on scalar types and some other on vectors of scalar types. Fixes #10147

4 files changed, 17 insertions(+), 0 deletions(-)

src/stage1/all_types.hpp+1
...@@ -1957,6 +1957,7 @@ struct ZigLLVMFnKey {...@@ -1957,6 +1957,7 @@ struct ZigLLVMFnKey {
1957 } bswap;1957 } bswap;
1958 struct {1958 struct {
1959 uint32_t bit_count;1959 uint32_t bit_count;
1960 uint32_t vector_len; // 0 means not a vector
1960 } bit_reverse;1961 } bit_reverse;
1961 } data;1962 } data;
1962};1963};
src/stage1/codegen.cpp+3
...@@ -5175,11 +5175,13 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, ZigType *expr_type, BuiltinFn...@@ -5175,11 +5175,13 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, ZigType *expr_type, BuiltinFn
5175 n_args = 2;5175 n_args = 2;
5176 key.id = ZigLLVMFnIdCtz;5176 key.id = ZigLLVMFnIdCtz;
5177 key.data.ctz.bit_count = (uint32_t)int_type->data.integral.bit_count;5177 key.data.ctz.bit_count = (uint32_t)int_type->data.integral.bit_count;
5178 key.data.ctz.vector_len = vector_len;
5178 } else if (fn_id == BuiltinFnIdClz) {5179 } else if (fn_id == BuiltinFnIdClz) {
5179 fn_name = "ctlz";5180 fn_name = "ctlz";
5180 n_args = 2;5181 n_args = 2;
5181 key.id = ZigLLVMFnIdClz;5182 key.id = ZigLLVMFnIdClz;
5182 key.data.clz.bit_count = (uint32_t)int_type->data.integral.bit_count;5183 key.data.clz.bit_count = (uint32_t)int_type->data.integral.bit_count;
5184 key.data.clz.vector_len = vector_len;
5183 } else if (fn_id == BuiltinFnIdPopCount) {5185 } else if (fn_id == BuiltinFnIdPopCount) {
5184 fn_name = "ctpop";5186 fn_name = "ctpop";
5185 n_args = 1;5187 n_args = 1;
...@@ -5197,6 +5199,7 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, ZigType *expr_type, BuiltinFn...@@ -5197,6 +5199,7 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, ZigType *expr_type, BuiltinFn
5197 n_args = 1;5199 n_args = 1;
5198 key.id = ZigLLVMFnIdBitReverse;5200 key.id = ZigLLVMFnIdBitReverse;
5199 key.data.bit_reverse.bit_count = (uint32_t)int_type->data.integral.bit_count;5201 key.data.bit_reverse.bit_count = (uint32_t)int_type->data.integral.bit_count;
5202 key.data.bit_reverse.vector_len = vector_len;
5200 } else {5203 } else {
5201 zig_unreachable();5204 zig_unreachable();
5202 }5205 }
test/behavior.zig+1
...@@ -128,6 +128,7 @@ test {...@@ -128,6 +128,7 @@ test {
128 _ = @import("behavior/bugs/7250.zig");128 _ = @import("behavior/bugs/7250.zig");
129 _ = @import("behavior/bugs/9584.zig");129 _ = @import("behavior/bugs/9584.zig");
130 _ = @import("behavior/bugs/9967.zig");130 _ = @import("behavior/bugs/9967.zig");
131 _ = @import("behavior/bugs/10147.zig");
131 _ = @import("behavior/byteswap.zig");132 _ = @import("behavior/byteswap.zig");
132 _ = @import("behavior/byval_arg_var.zig");133 _ = @import("behavior/byval_arg_var.zig");
133 _ = @import("behavior/call_stage1.zig");134 _ = @import("behavior/call_stage1.zig");
test/behavior/bugs/10147.zig created+12
...@@ -0,0 +1,12 @@
1const std = @import("std");
2
3test "uses correct LLVM builtin" {
4 var x: u32 = 0x1;
5 var y: @Vector(4, u32) = [_]u32{ 0x1, 0x1, 0x1, 0x1 };
6 // The stage1 compiler used to call the same builtin function for both
7 // scalar and vector inputs, causing the LLVM module verification to fail.
8 var a = @clz(u32, x);
9 var b = @clz(u32, y);
10 try std.testing.expectEqual(@as(u6, 31), a);
11 try std.testing.expectEqual([_]u6{ 31, 31, 31, 31 }, b);
12}