authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-07-26 19:49:16-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-07-27 00:49:25-07:00
log0f21d3d4d1a5cbb5254dbf55304347f4d5c3e9c5
tree4e0933b1300b0fe9fc8f005ab96b074901ad44d5
parentc3364b372f4fa67a681d599f1a7ddcd4c0154fd1

LLVM: always add argument attributes to calls

These are needed for correctness. There's no reason to only add them for function pointers. closes #16290

3 files changed, 74 insertions(+), 2 deletions(-)

src/codegen/llvm.zig+2-2
...@@ -5324,8 +5324,8 @@ pub const FuncGen = struct {...@@ -5324,8 +5324,8 @@ pub const FuncGen = struct {
5324 },5324 },
5325 };5325 };
53265326
5327 if (callee_ty.zigTypeTag(mod) == .Pointer) {5327 {
5328 // Add argument attributes for function pointer calls.5328 // Add argument attributes.
5329 it = iterateParamTypes(o, fn_info);5329 it = iterateParamTypes(o, fn_info);
5330 it.llvm_index += @intFromBool(sret);5330 it.llvm_index += @intFromBool(sret);
5331 it.llvm_index += @intFromBool(err_return_tracing);5331 it.llvm_index += @intFromBool(err_return_tracing);
test/c_abi/cfuncs.c+17
...@@ -1034,3 +1034,20 @@ struct ByRef __attribute__((sysv_abi)) c_explict_sys_v(struct ByRef in) {...@@ -1034,3 +1034,20 @@ struct ByRef __attribute__((sysv_abi)) c_explict_sys_v(struct ByRef in) {
1034 return in;1034 return in;
1035}1035}
1036#endif1036#endif
1037
1038
1039struct byval_tail_callsite_attr_Point {
1040 double x;
1041 double y;
1042} Point;
1043struct byval_tail_callsite_attr_Size {
1044 double width;
1045 double height;
1046} Size;
1047struct byval_tail_callsite_attr_Rect {
1048 struct byval_tail_callsite_attr_Point origin;
1049 struct byval_tail_callsite_attr_Size size;
1050};
1051double c_byval_tail_callsite_attr(struct byval_tail_callsite_attr_Rect in) {
1052 return in.size.width;
1053}
test/c_abi/main.zig+55
...@@ -1216,3 +1216,58 @@ test "explicit Win64 calling convention" {...@@ -1216,3 +1216,58 @@ test "explicit Win64 calling convention" {
1216 const res = c_explict_sys_v(.{ .val = 1, .arr = undefined });1216 const res = c_explict_sys_v(.{ .val = 1, .arr = undefined });
1217 try expect(res.val == 42);1217 try expect(res.val == 42);
1218}1218}
1219
1220const byval_tail_callsite_attr = struct {
1221 const struct_Point = extern struct {
1222 x: f64,
1223 y: f64,
1224 };
1225 const struct_Size = extern struct {
1226 width: f64,
1227 height: f64,
1228 };
1229 const struct_Rect = extern struct {
1230 origin: struct_Point,
1231 size: struct_Size,
1232 };
1233
1234 const Point = extern struct {
1235 x: f64,
1236 y: f64,
1237 };
1238
1239 const Size = extern struct {
1240 width: f64,
1241 height: f64,
1242 };
1243
1244 const MyRect = extern struct {
1245 origin: Point,
1246 size: Size,
1247
1248 fn run(self: MyRect) f64 {
1249 return c_byval_tail_callsite_attr(cast(self));
1250 }
1251
1252 fn cast(self: MyRect) struct_Rect {
1253 return @bitCast(self);
1254 }
1255
1256 extern fn c_byval_tail_callsite_attr(struct_Rect) f64;
1257 };
1258};
1259
1260test "byval tail callsite attribute" {
1261 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
1262 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
1263
1264 // Originally reported at https://github.com/ziglang/zig/issues/16290
1265 // the bug was that the extern function had the byval attribute, but
1266 // zig did not put the byval attribute at the callsite. Some LLVM optimization
1267 // passes would then pass undefined for that parameter.
1268 var v: byval_tail_callsite_attr.MyRect = .{
1269 .origin = .{ .x = 1, .y = 2 },
1270 .size = .{ .width = 3, .height = 4 },
1271 };
1272 try expect(v.run() == 3.0);
1273}