authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-08-07 07:45:36-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-08-08 21:32:50-04:00
log49cc1bff086e9c521c110b35692a87f75e25c7ad
tree27b9b730b13634960acd413a88da53a23374be4a
parent6577f52614e21dc43ccc2eb9ab80eeaa4fde9cd4

llvm: finish converting intrinsics


6 files changed, 525 insertions(+), 249 deletions(-)

src/codegen/llvm.zig+190-191
...@@ -5466,7 +5466,7 @@ pub const FuncGen = struct {...@@ -5466,7 +5466,7 @@ pub const FuncGen = struct {
5466 const result_alignment = Builder.Alignment.fromByteUnits(va_list_ty.abiAlignment(mod));5466 const result_alignment = Builder.Alignment.fromByteUnits(va_list_ty.abiAlignment(mod));
5467 const dest_list = try self.buildAlloca(llvm_va_list_ty, result_alignment);5467 const dest_list = try self.buildAlloca(llvm_va_list_ty, result_alignment);
54685468
5469 _ = try self.wip.callIntrinsic(.va_copy, &.{}, &.{ dest_list, src_list }, "");5469 _ = try self.wip.callIntrinsic(.none, .va_copy, &.{}, &.{ dest_list, src_list }, "");
5470 return if (isByRef(va_list_ty, mod))5470 return if (isByRef(va_list_ty, mod))
5471 dest_list5471 dest_list
5472 else5472 else
...@@ -5477,7 +5477,7 @@ pub const FuncGen = struct {...@@ -5477,7 +5477,7 @@ pub const FuncGen = struct {
5477 const un_op = self.air.instructions.items(.data)[inst].un_op;5477 const un_op = self.air.instructions.items(.data)[inst].un_op;
5478 const src_list = try self.resolveInst(un_op);5478 const src_list = try self.resolveInst(un_op);
54795479
5480 _ = try self.wip.callIntrinsic(.va_end, &.{}, &.{src_list}, "");5480 _ = try self.wip.callIntrinsic(.none, .va_end, &.{}, &.{src_list}, "");
5481 return .none;5481 return .none;
5482 }5482 }
54835483
...@@ -5490,7 +5490,7 @@ pub const FuncGen = struct {...@@ -5490,7 +5490,7 @@ pub const FuncGen = struct {
5490 const result_alignment = Builder.Alignment.fromByteUnits(va_list_ty.abiAlignment(mod));5490 const result_alignment = Builder.Alignment.fromByteUnits(va_list_ty.abiAlignment(mod));
5491 const dest_list = try self.buildAlloca(llvm_va_list_ty, result_alignment);5491 const dest_list = try self.buildAlloca(llvm_va_list_ty, result_alignment);
54925492
5493 _ = try self.wip.callIntrinsic(.va_start, &.{}, &.{dest_list}, "");5493 _ = try self.wip.callIntrinsic(.none, .va_start, &.{}, &.{dest_list}, "");
5494 return if (isByRef(va_list_ty, mod))5494 return if (isByRef(va_list_ty, mod))
5495 dest_list5495 dest_list
5496 else5496 else
...@@ -5600,8 +5600,8 @@ pub const FuncGen = struct {...@@ -5600,8 +5600,8 @@ pub const FuncGen = struct {
5600 const both_pl_block_end = self.wip.cursor.block;5600 const both_pl_block_end = self.wip.cursor.block;
56015601
5602 self.wip.cursor = .{ .block = end_block };5602 self.wip.cursor = .{ .block = end_block };
5603 const llvm_i1_0 = try o.builder.intValue(.i1, 0);5603 const llvm_i1_0 = Builder.Value.false;
5604 const llvm_i1_1 = try o.builder.intValue(.i1, 1);5604 const llvm_i1_1 = Builder.Value.true;
5605 const incoming_values: [3]Builder.Value = .{5605 const incoming_values: [3]Builder.Value = .{
5606 switch (op) {5606 switch (op) {
5607 .eq => llvm_i1_1,5607 .eq => llvm_i1_1,
...@@ -5822,7 +5822,7 @@ pub const FuncGen = struct {...@@ -5822,7 +5822,7 @@ pub const FuncGen = struct {
5822 if (can_elide_load)5822 if (can_elide_load)
5823 return payload_ptr;5823 return payload_ptr;
58245824
5825 return fg.loadByRef(payload_ptr, payload_ty, payload_alignment, false);5825 return fg.loadByRef(payload_ptr, payload_ty, payload_alignment, .normal);
5826 }5826 }
5827 const load_ty = err_union_llvm_ty.structFields(&o.builder)[offset];5827 const load_ty = err_union_llvm_ty.structFields(&o.builder)[offset];
5828 return fg.wip.load(.normal, load_ty, payload_ptr, payload_alignment, "");5828 return fg.wip.load(.normal, load_ty, payload_ptr, payload_alignment, "");
...@@ -6121,7 +6121,7 @@ pub const FuncGen = struct {...@@ -6121,7 +6121,7 @@ pub const FuncGen = struct {
6121 return ptr;6121 return ptr;
61226122
6123 const elem_alignment = Builder.Alignment.fromByteUnits(elem_ty.abiAlignment(mod));6123 const elem_alignment = Builder.Alignment.fromByteUnits(elem_ty.abiAlignment(mod));
6124 return self.loadByRef(ptr, elem_ty, elem_alignment, false);6124 return self.loadByRef(ptr, elem_ty, elem_alignment, .normal);
6125 }6125 }
61266126
6127 return self.load(ptr, slice_ty);6127 return self.load(ptr, slice_ty);
...@@ -6161,7 +6161,7 @@ pub const FuncGen = struct {...@@ -6161,7 +6161,7 @@ pub const FuncGen = struct {
6161 try self.wip.gep(.inbounds, array_llvm_ty, array_llvm_val, &indices, "");6161 try self.wip.gep(.inbounds, array_llvm_ty, array_llvm_val, &indices, "");
6162 if (canElideLoad(self, body_tail)) return elem_ptr;6162 if (canElideLoad(self, body_tail)) return elem_ptr;
6163 const elem_alignment = Builder.Alignment.fromByteUnits(elem_ty.abiAlignment(mod));6163 const elem_alignment = Builder.Alignment.fromByteUnits(elem_ty.abiAlignment(mod));
6164 return self.loadByRef(elem_ptr, elem_ty, elem_alignment, false);6164 return self.loadByRef(elem_ptr, elem_ty, elem_alignment, .normal);
6165 } else {6165 } else {
6166 const elem_llvm_ty = try o.lowerType(elem_ty);6166 const elem_llvm_ty = try o.lowerType(elem_ty);
6167 if (Air.refToIndex(bin_op.lhs)) |lhs_index| {6167 if (Air.refToIndex(bin_op.lhs)) |lhs_index| {
...@@ -6221,7 +6221,7 @@ pub const FuncGen = struct {...@@ -6221,7 +6221,7 @@ pub const FuncGen = struct {
6221 if (isByRef(elem_ty, mod)) {6221 if (isByRef(elem_ty, mod)) {
6222 if (self.canElideLoad(body_tail)) return ptr;6222 if (self.canElideLoad(body_tail)) return ptr;
6223 const elem_alignment = Builder.Alignment.fromByteUnits(elem_ty.abiAlignment(mod));6223 const elem_alignment = Builder.Alignment.fromByteUnits(elem_ty.abiAlignment(mod));
6224 return self.loadByRef(ptr, elem_ty, elem_alignment, false);6224 return self.loadByRef(ptr, elem_ty, elem_alignment, .normal);
6225 }6225 }
62266226
6227 return self.load(ptr, ptr_ty);6227 return self.load(ptr, ptr_ty);
...@@ -6351,7 +6351,7 @@ pub const FuncGen = struct {...@@ -6351,7 +6351,7 @@ pub const FuncGen = struct {
63516351
6352 assert(llvm_field.alignment != 0);6352 assert(llvm_field.alignment != 0);
6353 const field_alignment = Builder.Alignment.fromByteUnits(llvm_field.alignment);6353 const field_alignment = Builder.Alignment.fromByteUnits(llvm_field.alignment);
6354 return self.loadByRef(field_ptr, field_ty, field_alignment, false);6354 return self.loadByRef(field_ptr, field_ty, field_alignment, .normal);
6355 } else {6355 } else {
6356 return self.load(field_ptr, field_ptr_ty);6356 return self.load(field_ptr, field_ptr_ty);
6357 }6357 }
...@@ -6366,7 +6366,7 @@ pub const FuncGen = struct {...@@ -6366,7 +6366,7 @@ pub const FuncGen = struct {
6366 const payload_alignment = Builder.Alignment.fromByteUnits(layout.payload_align);6366 const payload_alignment = Builder.Alignment.fromByteUnits(layout.payload_align);
6367 if (isByRef(field_ty, mod)) {6367 if (isByRef(field_ty, mod)) {
6368 if (canElideLoad(self, body_tail)) return field_ptr;6368 if (canElideLoad(self, body_tail)) return field_ptr;
6369 return self.loadByRef(field_ptr, field_ty, payload_alignment, false);6369 return self.loadByRef(field_ptr, field_ty, payload_alignment, .normal);
6370 } else {6370 } else {
6371 return self.wip.load(.normal, llvm_field_ty, field_ptr, payload_alignment, "");6371 return self.wip.load(.normal, llvm_field_ty, field_ptr, payload_alignment, "");
6372 }6372 }
...@@ -7150,7 +7150,7 @@ pub const FuncGen = struct {...@@ -7150,7 +7150,7 @@ pub const FuncGen = struct {
7150 const payload_ptr = try self.wip.gepStruct(err_union_llvm_ty, operand, offset, "");7150 const payload_ptr = try self.wip.gepStruct(err_union_llvm_ty, operand, offset, "");
7151 if (isByRef(payload_ty, mod)) {7151 if (isByRef(payload_ty, mod)) {
7152 if (self.canElideLoad(body_tail)) return payload_ptr;7152 if (self.canElideLoad(body_tail)) return payload_ptr;
7153 return self.loadByRef(payload_ptr, payload_ty, payload_alignment, false);7153 return self.loadByRef(payload_ptr, payload_ty, payload_alignment, .normal);
7154 }7154 }
7155 const payload_llvm_ty = err_union_llvm_ty.structFields(&o.builder)[offset];7155 const payload_llvm_ty = err_union_llvm_ty.structFields(&o.builder)[offset];
7156 return self.wip.load(.normal, payload_llvm_ty, payload_ptr, payload_alignment, "");7156 return self.wip.load(.normal, payload_llvm_ty, payload_ptr, payload_alignment, "");
...@@ -7346,7 +7346,7 @@ pub const FuncGen = struct {...@@ -7346,7 +7346,7 @@ pub const FuncGen = struct {
7346 const o = self.dg.object;7346 const o = self.dg.object;
7347 const pl_op = self.air.instructions.items(.data)[inst].pl_op;7347 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
7348 const index = pl_op.payload;7348 const index = pl_op.payload;
7349 return self.wip.callIntrinsic(.@"wasm.memory.size", &.{.i32}, &.{7349 return self.wip.callIntrinsic(.none, .@"wasm.memory.size", &.{.i32}, &.{
7350 try o.builder.intValue(.i32, index),7350 try o.builder.intValue(.i32, index),
7351 }, "");7351 }, "");
7352 }7352 }
...@@ -7355,7 +7355,7 @@ pub const FuncGen = struct {...@@ -7355,7 +7355,7 @@ pub const FuncGen = struct {
7355 const o = self.dg.object;7355 const o = self.dg.object;
7356 const pl_op = self.air.instructions.items(.data)[inst].pl_op;7356 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
7357 const index = pl_op.payload;7357 const index = pl_op.payload;
7358 return self.wip.callIntrinsic(.@"wasm.memory.grow", &.{.i32}, &.{7358 return self.wip.callIntrinsic(.none, .@"wasm.memory.grow", &.{.i32}, &.{
7359 try o.builder.intValue(.i32, index), try self.resolveInst(pl_op.operand),7359 try o.builder.intValue(.i32, index), try self.resolveInst(pl_op.operand),
7360 }, "");7360 }, "");
7361 }7361 }
...@@ -7371,13 +7371,11 @@ pub const FuncGen = struct {...@@ -7371,13 +7371,11 @@ pub const FuncGen = struct {
7371 const index = try self.resolveInst(extra.lhs);7371 const index = try self.resolveInst(extra.lhs);
7372 const operand = try self.resolveInst(extra.rhs);7372 const operand = try self.resolveInst(extra.rhs);
73737373
7374 const kind: Builder.MemoryAccessKind = switch (vector_ptr_ty.isVolatilePtr(mod)) {7374 const access_kind: Builder.MemoryAccessKind =
7375 false => .normal,7375 if (vector_ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal;
7376 true => .@"volatile",
7377 };
7378 const elem_llvm_ty = try o.lowerType(vector_ptr_ty.childType(mod));7376 const elem_llvm_ty = try o.lowerType(vector_ptr_ty.childType(mod));
7379 const alignment = Builder.Alignment.fromByteUnits(vector_ptr_ty.ptrAlignment(mod));7377 const alignment = Builder.Alignment.fromByteUnits(vector_ptr_ty.ptrAlignment(mod));
7380 const loaded = try self.wip.load(kind, elem_llvm_ty, vector_ptr, alignment, "");7378 const loaded = try self.wip.load(access_kind, elem_llvm_ty, vector_ptr, alignment, "");
73817379
7382 const new_vector = try self.wip.insertElement(loaded, operand, index, "");7380 const new_vector = try self.wip.insertElement(loaded, operand, index, "");
7383 _ = try self.store(vector_ptr, vector_ptr_ty, new_vector, .none);7381 _ = try self.store(vector_ptr, vector_ptr_ty, new_vector, .none);
...@@ -7395,6 +7393,7 @@ pub const FuncGen = struct {...@@ -7395,6 +7393,7 @@ pub const FuncGen = struct {
73957393
7396 if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.fmin, inst_ty, 2, .{ lhs, rhs });7394 if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.fmin, inst_ty, 2, .{ lhs, rhs });
7397 return self.wip.callIntrinsic(7395 return self.wip.callIntrinsic(
7396 .none,
7398 if (scalar_ty.isSignedInt(mod)) .smin else .umin,7397 if (scalar_ty.isSignedInt(mod)) .smin else .umin,
7399 &.{try o.lowerType(inst_ty)},7398 &.{try o.lowerType(inst_ty)},
7400 &.{ lhs, rhs },7399 &.{ lhs, rhs },
...@@ -7413,6 +7412,7 @@ pub const FuncGen = struct {...@@ -7413,6 +7412,7 @@ pub const FuncGen = struct {
74137412
7414 if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.fmax, inst_ty, 2, .{ lhs, rhs });7413 if (scalar_ty.isAnyFloat()) return self.buildFloatOp(.fmax, inst_ty, 2, .{ lhs, rhs });
7415 return self.wip.callIntrinsic(7414 return self.wip.callIntrinsic(
7415 .none,
7416 if (scalar_ty.isSignedInt(mod)) .smax else .umax,7416 if (scalar_ty.isSignedInt(mod)) .smax else .umax,
7417 &.{try o.lowerType(inst_ty)},7417 &.{try o.lowerType(inst_ty)},
7418 &.{ lhs, rhs },7418 &.{ lhs, rhs },
...@@ -7462,12 +7462,19 @@ pub const FuncGen = struct {...@@ -7462,12 +7462,19 @@ pub const FuncGen = struct {
74627462
7463 const intrinsic = if (scalar_ty.isSignedInt(mod)) signed_intrinsic else unsigned_intrinsic;7463 const intrinsic = if (scalar_ty.isSignedInt(mod)) signed_intrinsic else unsigned_intrinsic;
7464 const llvm_inst_ty = try o.lowerType(inst_ty);7464 const llvm_inst_ty = try o.lowerType(inst_ty);
7465 const results = try fg.wip.callIntrinsic(intrinsic, &.{llvm_inst_ty}, &.{ lhs, rhs }, "");7465 const results =
7466 try fg.wip.callIntrinsic(.none, intrinsic, &.{llvm_inst_ty}, &.{ lhs, rhs }, "");
74667467
7467 const overflow_bits = try fg.wip.extractValue(results, &.{1}, "");7468 const overflow_bits = try fg.wip.extractValue(results, &.{1}, "");
7468 const overflow_bits_ty = overflow_bits.typeOfWip(&fg.wip);7469 const overflow_bits_ty = overflow_bits.typeOfWip(&fg.wip);
7469 const overflow_bit = if (overflow_bits_ty.isVector(&o.builder))7470 const overflow_bit = if (overflow_bits_ty.isVector(&o.builder))
7470 try fg.wip.callIntrinsic(.@"vector.reduce.or", &.{overflow_bits_ty}, &.{overflow_bits}, "")7471 try fg.wip.callIntrinsic(
7472 .none,
7473 .@"vector.reduce.or",
7474 &.{overflow_bits_ty},
7475 &.{overflow_bits},
7476 "",
7477 )
7471 else7478 else
7472 overflow_bits;7479 overflow_bits;
74737480
...@@ -7501,6 +7508,7 @@ pub const FuncGen = struct {...@@ -7501,6 +7508,7 @@ pub const FuncGen = struct {
75017508
7502 if (scalar_ty.isAnyFloat()) return self.todo("saturating float add", .{});7509 if (scalar_ty.isAnyFloat()) return self.todo("saturating float add", .{});
7503 return self.wip.callIntrinsic(7510 return self.wip.callIntrinsic(
7511 .none,
7504 if (scalar_ty.isSignedInt(mod)) .@"sadd.sat" else .@"uadd.sat",7512 if (scalar_ty.isSignedInt(mod)) .@"sadd.sat" else .@"uadd.sat",
7505 &.{try o.lowerType(inst_ty)},7513 &.{try o.lowerType(inst_ty)},
7506 &.{ lhs, rhs },7514 &.{ lhs, rhs },
...@@ -7542,6 +7550,7 @@ pub const FuncGen = struct {...@@ -7542,6 +7550,7 @@ pub const FuncGen = struct {
75427550
7543 if (scalar_ty.isAnyFloat()) return self.todo("saturating float sub", .{});7551 if (scalar_ty.isAnyFloat()) return self.todo("saturating float sub", .{});
7544 return self.wip.callIntrinsic(7552 return self.wip.callIntrinsic(
7553 .none,
7545 if (scalar_ty.isSignedInt(mod)) .@"ssub.sat" else .@"usub.sat",7554 if (scalar_ty.isSignedInt(mod)) .@"ssub.sat" else .@"usub.sat",
7546 &.{try o.lowerType(inst_ty)},7555 &.{try o.lowerType(inst_ty)},
7547 &.{ lhs, rhs },7556 &.{ lhs, rhs },
...@@ -7583,6 +7592,7 @@ pub const FuncGen = struct {...@@ -7583,6 +7592,7 @@ pub const FuncGen = struct {
75837592
7584 if (scalar_ty.isAnyFloat()) return self.todo("saturating float mul", .{});7593 if (scalar_ty.isAnyFloat()) return self.todo("saturating float mul", .{});
7585 return self.wip.callIntrinsic(7594 return self.wip.callIntrinsic(
7595 .none,
7586 if (scalar_ty.isSignedInt(mod)) .@"smul.fix.sat" else .@"umul.fix.sat",7596 if (scalar_ty.isSignedInt(mod)) .@"smul.fix.sat" else .@"umul.fix.sat",
7587 &.{try o.lowerType(inst_ty)},7597 &.{try o.lowerType(inst_ty)},
7588 &.{ lhs, rhs, try o.builder.intValue(.i32, 0) },7598 &.{ lhs, rhs, try o.builder.intValue(.i32, 0) },
...@@ -7793,7 +7803,8 @@ pub const FuncGen = struct {...@@ -7793,7 +7803,8 @@ pub const FuncGen = struct {
7793 const intrinsic = if (scalar_ty.isSignedInt(mod)) signed_intrinsic else unsigned_intrinsic;7803 const intrinsic = if (scalar_ty.isSignedInt(mod)) signed_intrinsic else unsigned_intrinsic;
7794 const llvm_inst_ty = try o.lowerType(inst_ty);7804 const llvm_inst_ty = try o.lowerType(inst_ty);
7795 const llvm_lhs_ty = try o.lowerType(lhs_ty);7805 const llvm_lhs_ty = try o.lowerType(lhs_ty);
7796 const results = try self.wip.callIntrinsic(intrinsic, &.{llvm_lhs_ty}, &.{ lhs, rhs }, "");7806 const results =
7807 try self.wip.callIntrinsic(.none, intrinsic, &.{llvm_lhs_ty}, &.{ lhs, rhs }, "");
77977808
7798 const result_val = try self.wip.extractValue(results, &.{0}, "");7809 const result_val = try self.wip.extractValue(results, &.{0}, "");
7799 const overflow_bit = try self.wip.extractValue(results, &.{1}, "");7810 const overflow_bit = try self.wip.extractValue(results, &.{1}, "");
...@@ -7998,27 +8009,49 @@ pub const FuncGen = struct {...@@ -7998,27 +8009,49 @@ pub const FuncGen = struct {
7998 if (op != .tan and intrinsicsAllowed(scalar_ty, target)) switch (op) {8009 if (op != .tan and intrinsicsAllowed(scalar_ty, target)) switch (op) {
7999 // Some operations are dedicated LLVM instructions, not available as intrinsics8010 // Some operations are dedicated LLVM instructions, not available as intrinsics
8000 .neg => return self.wip.un(.fneg, params[0], ""),8011 .neg => return self.wip.un(.fneg, params[0], ""),
8001 .add => return self.wip.bin(.fadd, params[0], params[1], ""),8012 .add, .sub, .mul, .div, .fmod => return self.wip.bin(switch (op) {
8002 .sub => return self.wip.bin(.fsub, params[0], params[1], ""),8013 .add => .fadd,
8003 .mul => return self.wip.bin(.fmul, params[0], params[1], ""),8014 .sub => .fsub,
8004 .div => return self.wip.bin(.fdiv, params[0], params[1], ""),8015 .mul => .fmul,
8005 .fmod => return self.wip.bin(.frem, params[0], params[1], ""),8016 .div => .fdiv,
8006 .fmax => return self.wip.callIntrinsic(.maxnum, &.{llvm_ty}, &params, ""),8017 .fmod => .frem,
8007 .fmin => return self.wip.callIntrinsic(.minnum, &.{llvm_ty}, &params, ""),8018 else => unreachable,
8008 .ceil => return self.wip.callIntrinsic(.ceil, &.{llvm_ty}, &params, ""),8019 }, params[0], params[1], ""),
8009 .cos => return self.wip.callIntrinsic(.cos, &.{llvm_ty}, &params, ""),8020 .fmax,
8010 .exp => return self.wip.callIntrinsic(.exp, &.{llvm_ty}, &params, ""),8021 .fmin,
8011 .exp2 => return self.wip.callIntrinsic(.exp2, &.{llvm_ty}, &params, ""),8022 .ceil,
8012 .fabs => return self.wip.callIntrinsic(.fabs, &.{llvm_ty}, &params, ""),8023 .cos,
8013 .floor => return self.wip.callIntrinsic(.floor, &.{llvm_ty}, &params, ""),8024 .exp,
8014 .log => return self.wip.callIntrinsic(.log, &.{llvm_ty}, &params, ""),8025 .exp2,
8015 .log10 => return self.wip.callIntrinsic(.log10, &.{llvm_ty}, &params, ""),8026 .fabs,
8016 .log2 => return self.wip.callIntrinsic(.log2, &.{llvm_ty}, &params, ""),8027 .floor,
8017 .round => return self.wip.callIntrinsic(.round, &.{llvm_ty}, &params, ""),8028 .log,
8018 .sin => return self.wip.callIntrinsic(.sin, &.{llvm_ty}, &params, ""),8029 .log10,
8019 .sqrt => return self.wip.callIntrinsic(.sqrt, &.{llvm_ty}, &params, ""),8030 .log2,
8020 .trunc => return self.wip.callIntrinsic(.trunc, &.{llvm_ty}, &params, ""),8031 .round,
8021 .fma => return self.wip.callIntrinsic(.fma, &.{llvm_ty}, &params, ""),8032 .sin,
8033 .sqrt,
8034 .trunc,
8035 .fma,
8036 => return self.wip.callIntrinsic(.none, switch (op) {
8037 .fmax => .maxnum,
8038 .fmin => .minnum,
8039 .ceil => .ceil,
8040 .cos => .cos,
8041 .exp => .exp,
8042 .exp2 => .exp2,
8043 .fabs => .fabs,
8044 .floor => .floor,
8045 .log => .log,
8046 .log10 => .log10,
8047 .log2 => .log2,
8048 .round => .round,
8049 .sin => .sin,
8050 .sqrt => .sqrt,
8051 .trunc => .trunc,
8052 .fma => .fma,
8053 else => unreachable,
8054 }, &.{llvm_ty}, &params, ""),
8022 .tan => unreachable,8055 .tan => unreachable,
8023 };8056 };
80248057
...@@ -8215,6 +8248,7 @@ pub const FuncGen = struct {...@@ -8215,6 +8248,7 @@ pub const FuncGen = struct {
8215 const llvm_lhs_ty = try o.lowerType(lhs_ty);8248 const llvm_lhs_ty = try o.lowerType(lhs_ty);
8216 const llvm_lhs_scalar_ty = llvm_lhs_ty.scalarType(&o.builder);8249 const llvm_lhs_scalar_ty = llvm_lhs_ty.scalarType(&o.builder);
8217 const result = try self.wip.callIntrinsic(8250 const result = try self.wip.callIntrinsic(
8251 .none,
8218 if (lhs_scalar_ty.isSignedInt(mod)) .@"sshl.sat" else .@"ushl.sat",8252 if (lhs_scalar_ty.isSignedInt(mod)) .@"sshl.sat" else .@"ushl.sat",
8219 &.{llvm_lhs_ty},8253 &.{llvm_lhs_ty},
8220 &.{ lhs, casted_rhs },8254 &.{ lhs, casted_rhs },
...@@ -8588,21 +8622,14 @@ pub const FuncGen = struct {...@@ -8588,21 +8622,14 @@ pub const FuncGen = struct {
8588 // Even if safety is disabled, we still emit a memset to undefined since it conveys8622 // Even if safety is disabled, we still emit a memset to undefined since it conveys
8589 // extra information to LLVM. However, safety makes the difference between using8623 // extra information to LLVM. However, safety makes the difference between using
8590 // 0xaa or actual undefined for the fill byte.8624 // 0xaa or actual undefined for the fill byte.
8591 const fill_byte = if (safety)8625 const len = try o.builder.intValue(try o.lowerType(Type.usize), operand_ty.abiSize(mod));
8592 try o.builder.intConst(.i8, 0xaa)8626 _ = try self.wip.callMemSet(
8593 else8627 dest_ptr,
8594 try o.builder.undefConst(.i8);8628 Builder.Alignment.fromByteUnits(ptr_ty.ptrAlignment(mod)),
8595 const operand_size = operand_ty.abiSize(mod);8629 if (safety) try o.builder.intValue(.i8, 0xaa) else try o.builder.undefValue(.i8),
8596 const usize_ty = try o.lowerType(Type.usize);8630 len,
8597 const len = try o.builder.intValue(usize_ty, operand_size);8631 if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal,
8598 const dest_ptr_align = Builder.Alignment.fromByteUnits(ptr_ty.ptrAlignment(mod));8632 );
8599 _ = (try self.wip.unimplemented(.void, "")).finish(self.builder.buildMemSet(
8600 dest_ptr.toLlvm(&self.wip),
8601 fill_byte.toLlvm(&o.builder),
8602 len.toLlvm(&self.wip),
8603 @intCast(dest_ptr_align.toByteUnits() orelse 0),
8604 ptr_ty.isVolatilePtr(mod),
8605 ), &self.wip);
8606 if (safety and mod.comp.bin_file.options.valgrind) {8633 if (safety and mod.comp.bin_file.options.valgrind) {
8607 try self.valgrindMarkUndef(dest_ptr, len);8634 try self.valgrindMarkUndef(dest_ptr, len);
8608 }8635 }
...@@ -8655,14 +8682,14 @@ pub const FuncGen = struct {...@@ -8655,14 +8682,14 @@ pub const FuncGen = struct {
86558682
8656 fn airTrap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8683 fn airTrap(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8657 _ = inst;8684 _ = inst;
8658 _ = try self.wip.callIntrinsic(.trap, &.{}, &.{}, "");8685 _ = try self.wip.callIntrinsic(.none, .trap, &.{}, &.{}, "");
8659 _ = try self.wip.@"unreachable"();8686 _ = try self.wip.@"unreachable"();
8660 return .none;8687 return .none;
8661 }8688 }
86628689
8663 fn airBreakpoint(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8690 fn airBreakpoint(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8664 _ = inst;8691 _ = inst;
8665 _ = try self.wip.callIntrinsic(.debugtrap, &.{}, &.{}, "");8692 _ = try self.wip.callIntrinsic(.none, .debugtrap, &.{}, &.{}, "");
8666 return .none;8693 return .none;
8667 }8694 }
86688695
...@@ -8674,7 +8701,7 @@ pub const FuncGen = struct {...@@ -8674,7 +8701,7 @@ pub const FuncGen = struct {
8674 // https://github.com/ziglang/zig/issues/119468701 // https://github.com/ziglang/zig/issues/11946
8675 return o.builder.intValue(llvm_usize, 0);8702 return o.builder.intValue(llvm_usize, 0);
8676 }8703 }
8677 const result = try self.wip.callIntrinsic(.returnaddress, &.{}, &.{8704 const result = try self.wip.callIntrinsic(.none, .returnaddress, &.{}, &.{
8678 try o.builder.intValue(.i32, 0),8705 try o.builder.intValue(.i32, 0),
8679 }, "");8706 }, "");
8680 return self.wip.cast(.ptrtoint, result, llvm_usize, "");8707 return self.wip.cast(.ptrtoint, result, llvm_usize, "");
...@@ -8683,7 +8710,7 @@ pub const FuncGen = struct {...@@ -8683,7 +8710,7 @@ pub const FuncGen = struct {
8683 fn airFrameAddress(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {8710 fn airFrameAddress(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
8684 _ = inst;8711 _ = inst;
8685 const o = self.dg.object;8712 const o = self.dg.object;
8686 const result = try self.wip.callIntrinsic(.frameaddress, &.{.ptr}, &.{8713 const result = try self.wip.callIntrinsic(.none, .frameaddress, &.{.ptr}, &.{
8687 try o.builder.intValue(.i32, 0),8714 try o.builder.intValue(.i32, 0),
8688 }, "");8715 }, "");
8689 return self.wip.cast(.ptrtoint, result, try o.lowerType(Type.usize), "");8716 return self.wip.cast(.ptrtoint, result, try o.lowerType(Type.usize), "");
...@@ -8835,16 +8862,14 @@ pub const FuncGen = struct {...@@ -8835,16 +8862,14 @@ pub const FuncGen = struct {
8835 const ptr_alignment = Builder.Alignment.fromByteUnits(8862 const ptr_alignment = Builder.Alignment.fromByteUnits(
8836 info.flags.alignment.toByteUnitsOptional() orelse info.child.toType().abiAlignment(mod),8863 info.flags.alignment.toByteUnitsOptional() orelse info.child.toType().abiAlignment(mod),
8837 );8864 );
8838 const ptr_kind: Builder.MemoryAccessKind = switch (info.flags.is_volatile) {8865 const access_kind: Builder.MemoryAccessKind =
8839 false => .normal,8866 if (info.flags.is_volatile) .@"volatile" else .normal;
8840 true => .@"volatile",
8841 };
8842 const elem_llvm_ty = try o.lowerType(elem_ty);8867 const elem_llvm_ty = try o.lowerType(elem_ty);
88438868
8844 if (llvm_abi_ty != .none) {8869 if (llvm_abi_ty != .none) {
8845 // operand needs widening and truncating8870 // operand needs widening and truncating
8846 const loaded = try self.wip.loadAtomic(8871 const loaded = try self.wip.loadAtomic(
8847 ptr_kind,8872 access_kind,
8848 llvm_abi_ty,8873 llvm_abi_ty,
8849 ptr,8874 ptr,
8850 self.sync_scope,8875 self.sync_scope,
...@@ -8855,7 +8880,7 @@ pub const FuncGen = struct {...@@ -8855,7 +8880,7 @@ pub const FuncGen = struct {
8855 return self.wip.cast(.trunc, loaded, elem_llvm_ty, "");8880 return self.wip.cast(.trunc, loaded, elem_llvm_ty, "");
8856 }8881 }
8857 return self.wip.loadAtomic(8882 return self.wip.loadAtomic(
8858 ptr_kind,8883 access_kind,
8859 elem_llvm_ty,8884 elem_llvm_ty,
8860 ptr,8885 ptr,
8861 self.sync_scope,8886 self.sync_scope,
...@@ -8902,7 +8927,8 @@ pub const FuncGen = struct {...@@ -8902,7 +8927,8 @@ pub const FuncGen = struct {
8902 const elem_ty = self.typeOf(bin_op.rhs);8927 const elem_ty = self.typeOf(bin_op.rhs);
8903 const dest_ptr_align = Builder.Alignment.fromByteUnits(ptr_ty.ptrAlignment(mod));8928 const dest_ptr_align = Builder.Alignment.fromByteUnits(ptr_ty.ptrAlignment(mod));
8904 const dest_ptr = try self.sliceOrArrayPtr(dest_slice, ptr_ty);8929 const dest_ptr = try self.sliceOrArrayPtr(dest_slice, ptr_ty);
8905 const is_volatile = ptr_ty.isVolatilePtr(mod);8930 const access_kind: Builder.MemoryAccessKind =
8931 if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal;
89068932
8907 // Any WebAssembly runtime will trap when the destination pointer is out-of-bounds, regardless8933 // Any WebAssembly runtime will trap when the destination pointer is out-of-bounds, regardless
8908 // of the length. This means we need to emit a check where we skip the memset when the length8934 // of the length. This means we need to emit a check where we skip the memset when the length
...@@ -8923,17 +8949,10 @@ pub const FuncGen = struct {...@@ -8923,17 +8949,10 @@ pub const FuncGen = struct {
8923 try o.builder.undefValue(.i8);8949 try o.builder.undefValue(.i8);
8924 const len = try self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);8950 const len = try self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);
8925 if (intrinsic_len0_traps) {8951 if (intrinsic_len0_traps) {
8926 try self.safeWasmMemset(dest_ptr, fill_byte, len, dest_ptr_align, is_volatile);8952 try self.safeWasmMemset(dest_ptr, fill_byte, len, dest_ptr_align, access_kind);
8927 } else {8953 } else {
8928 _ = (try self.wip.unimplemented(.void, "")).finish(self.builder.buildMemSet(8954 _ = try self.wip.callMemSet(dest_ptr, dest_ptr_align, fill_byte, len, access_kind);
8929 dest_ptr.toLlvm(&self.wip),
8930 fill_byte.toLlvm(&self.wip),
8931 len.toLlvm(&self.wip),
8932 @intCast(dest_ptr_align.toByteUnits() orelse 0),
8933 is_volatile,
8934 ), &self.wip);
8935 }8955 }
8936
8937 if (safety and mod.comp.bin_file.options.valgrind) {8956 if (safety and mod.comp.bin_file.options.valgrind) {
8938 try self.valgrindMarkUndef(dest_ptr, len);8957 try self.valgrindMarkUndef(dest_ptr, len);
8939 }8958 }
...@@ -8945,19 +8964,12 @@ pub const FuncGen = struct {...@@ -8945,19 +8964,12 @@ pub const FuncGen = struct {
8945 // repeating byte pattern of 0 bytes. In such case, the memset8964 // repeating byte pattern of 0 bytes. In such case, the memset
8946 // intrinsic can be used.8965 // intrinsic can be used.
8947 if (try elem_val.hasRepeatedByteRepr(elem_ty, mod)) |byte_val| {8966 if (try elem_val.hasRepeatedByteRepr(elem_ty, mod)) |byte_val| {
8948 const fill_byte = try self.resolveValue(.{ .ty = Type.u8, .val = byte_val });8967 const fill_byte = try o.builder.intValue(.i8, byte_val);
8949 const len = try self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);8968 const len = try self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);
8950
8951 if (intrinsic_len0_traps) {8969 if (intrinsic_len0_traps) {
8952 try self.safeWasmMemset(dest_ptr, fill_byte.toValue(), len, dest_ptr_align, is_volatile);8970 try self.safeWasmMemset(dest_ptr, fill_byte, len, dest_ptr_align, access_kind);
8953 } else {8971 } else {
8954 _ = (try self.wip.unimplemented(.void, "")).finish(self.builder.buildMemSet(8972 _ = try self.wip.callMemSet(dest_ptr, dest_ptr_align, fill_byte, len, access_kind);
8955 dest_ptr.toLlvm(&self.wip),
8956 fill_byte.toLlvm(&o.builder),
8957 len.toLlvm(&self.wip),
8958 @intCast(dest_ptr_align.toByteUnits() orelse 0),
8959 is_volatile,
8960 ), &self.wip);
8961 }8973 }
8962 return .none;8974 return .none;
8963 }8975 }
...@@ -8972,15 +8984,9 @@ pub const FuncGen = struct {...@@ -8972,15 +8984,9 @@ pub const FuncGen = struct {
8972 const len = try self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);8984 const len = try self.sliceOrArrayLenInBytes(dest_slice, ptr_ty);
89738985
8974 if (intrinsic_len0_traps) {8986 if (intrinsic_len0_traps) {
8975 try self.safeWasmMemset(dest_ptr, fill_byte, len, dest_ptr_align, is_volatile);8987 try self.safeWasmMemset(dest_ptr, fill_byte, len, dest_ptr_align, access_kind);
8976 } else {8988 } else {
8977 _ = (try self.wip.unimplemented(.void, "")).finish(self.builder.buildMemSet(8989 _ = try self.wip.callMemSet(dest_ptr, dest_ptr_align, fill_byte, len, access_kind);
8978 dest_ptr.toLlvm(&self.wip),
8979 fill_byte.toLlvm(&self.wip),
8980 len.toLlvm(&self.wip),
8981 @intCast(dest_ptr_align.toByteUnits() orelse 0),
8982 is_volatile,
8983 ), &self.wip);
8984 }8990 }
8985 return .none;8991 return .none;
8986 }8992 }
...@@ -9006,10 +9012,10 @@ pub const FuncGen = struct {...@@ -9006,10 +9012,10 @@ pub const FuncGen = struct {
9006 const body_block = try self.wip.block(1, "InlineMemsetBody");9012 const body_block = try self.wip.block(1, "InlineMemsetBody");
9007 const end_block = try self.wip.block(1, "InlineMemsetEnd");9013 const end_block = try self.wip.block(1, "InlineMemsetEnd");
90089014
9009 const usize_ty = try o.lowerType(Type.usize);9015 const llvm_usize_ty = try o.lowerType(Type.usize);
9010 const len = switch (ptr_ty.ptrSize(mod)) {9016 const len = switch (ptr_ty.ptrSize(mod)) {
9011 .Slice => try self.wip.extractValue(dest_slice, &.{1}, ""),9017 .Slice => try self.wip.extractValue(dest_slice, &.{1}, ""),
9012 .One => try o.builder.intValue(usize_ty, ptr_ty.childType(mod).arrayLen(mod)),9018 .One => try o.builder.intValue(llvm_usize_ty, ptr_ty.childType(mod).arrayLen(mod)),
9013 .Many, .C => unreachable,9019 .Many, .C => unreachable,
9014 };9020 };
9015 const elem_llvm_ty = try o.lowerType(elem_ty);9021 const elem_llvm_ty = try o.lowerType(elem_ty);
...@@ -9022,25 +9028,22 @@ pub const FuncGen = struct {...@@ -9022,25 +9028,22 @@ pub const FuncGen = struct {
9022 _ = try self.wip.brCond(end, body_block, end_block);9028 _ = try self.wip.brCond(end, body_block, end_block);
90239029
9024 self.wip.cursor = .{ .block = body_block };9030 self.wip.cursor = .{ .block = body_block };
9025 const elem_abi_alignment = elem_ty.abiAlignment(mod);9031 const elem_abi_align = elem_ty.abiAlignment(mod);
9026 const it_ptr_alignment = Builder.Alignment.fromByteUnits(9032 const it_ptr_align = Builder.Alignment.fromByteUnits(
9027 @min(elem_abi_alignment, dest_ptr_align.toByteUnits() orelse std.math.maxInt(u64)),9033 @min(elem_abi_align, dest_ptr_align.toByteUnits() orelse std.math.maxInt(u64)),
9028 );9034 );
9029 if (isByRef(elem_ty, mod)) {9035 if (isByRef(elem_ty, mod)) {
9030 _ = (try self.wip.unimplemented(.void, "")).finish(self.builder.buildMemCpy(9036 _ = try self.wip.callMemCpy(
9031 it_ptr.toValue().toLlvm(&self.wip),9037 it_ptr.toValue(),
9032 @intCast(it_ptr_alignment.toByteUnits() orelse 0),9038 it_ptr_align,
9033 value.toLlvm(&self.wip),9039 value,
9034 elem_abi_alignment,9040 Builder.Alignment.fromByteUnits(elem_abi_align),
9035 (try o.builder.intConst(usize_ty, elem_abi_size)).toLlvm(&o.builder),9041 try o.builder.intValue(llvm_usize_ty, elem_abi_size),
9036 is_volatile,9042 access_kind,
9037 ), &self.wip);9043 );
9038 } else _ = try self.wip.store(switch (is_volatile) {9044 } else _ = try self.wip.store(access_kind, value, it_ptr.toValue(), it_ptr_align);
9039 false => .normal,
9040 true => .@"volatile",
9041 }, value, it_ptr.toValue(), it_ptr_alignment);
9042 const next_ptr = try self.wip.gep(.inbounds, elem_llvm_ty, it_ptr.toValue(), &.{9045 const next_ptr = try self.wip.gep(.inbounds, elem_llvm_ty, it_ptr.toValue(), &.{
9043 try o.builder.intValue(usize_ty, 1),9046 try o.builder.intValue(llvm_usize_ty, 1),
9044 }, "");9047 }, "");
9045 _ = try self.wip.br(loop_block);9048 _ = try self.wip.br(loop_block);
90469049
...@@ -9055,7 +9058,7 @@ pub const FuncGen = struct {...@@ -9055,7 +9058,7 @@ pub const FuncGen = struct {
9055 fill_byte: Builder.Value,9058 fill_byte: Builder.Value,
9056 len: Builder.Value,9059 len: Builder.Value,
9057 dest_ptr_align: Builder.Alignment,9060 dest_ptr_align: Builder.Alignment,
9058 is_volatile: bool,9061 access_kind: Builder.MemoryAccessKind,
9059 ) !void {9062 ) !void {
9060 const o = self.dg.object;9063 const o = self.dg.object;
9061 const llvm_usize_ty = try o.lowerType(Type.usize);9064 const llvm_usize_ty = try o.lowerType(Type.usize);
...@@ -9064,13 +9067,7 @@ pub const FuncGen = struct {...@@ -9064,13 +9067,7 @@ pub const FuncGen = struct {
9064 const end_block = try self.wip.block(2, "MemsetTrapEnd");9067 const end_block = try self.wip.block(2, "MemsetTrapEnd");
9065 _ = try self.wip.brCond(cond, memset_block, end_block);9068 _ = try self.wip.brCond(cond, memset_block, end_block);
9066 self.wip.cursor = .{ .block = memset_block };9069 self.wip.cursor = .{ .block = memset_block };
9067 _ = (try self.wip.unimplemented(.void, "")).finish(self.builder.buildMemSet(9070 _ = try self.wip.callMemSet(dest_ptr, dest_ptr_align, fill_byte, len, access_kind);
9068 dest_ptr.toLlvm(&self.wip),
9069 fill_byte.toLlvm(&self.wip),
9070 len.toLlvm(&self.wip),
9071 @intCast(dest_ptr_align.toByteUnits() orelse 0),
9072 is_volatile,
9073 ), &self.wip);
9074 _ = try self.wip.br(end_block);9071 _ = try self.wip.br(end_block);
9075 self.wip.cursor = .{ .block = end_block };9072 self.wip.cursor = .{ .block = end_block };
9076 }9073 }
...@@ -9086,7 +9083,8 @@ pub const FuncGen = struct {...@@ -9086,7 +9083,8 @@ pub const FuncGen = struct {
9086 const src_ptr = try self.sliceOrArrayPtr(src_slice, src_ptr_ty);9083 const src_ptr = try self.sliceOrArrayPtr(src_slice, src_ptr_ty);
9087 const len = try self.sliceOrArrayLenInBytes(dest_slice, dest_ptr_ty);9084 const len = try self.sliceOrArrayLenInBytes(dest_slice, dest_ptr_ty);
9088 const dest_ptr = try self.sliceOrArrayPtr(dest_slice, dest_ptr_ty);9085 const dest_ptr = try self.sliceOrArrayPtr(dest_slice, dest_ptr_ty);
9089 const is_volatile = src_ptr_ty.isVolatilePtr(mod) or dest_ptr_ty.isVolatilePtr(mod);9086 const access_kind: Builder.MemoryAccessKind = if (src_ptr_ty.isVolatilePtr(mod) or
9087 dest_ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal;
90909088
9091 // When bulk-memory is enabled, this will be lowered to WebAssembly's memory.copy instruction.9089 // When bulk-memory is enabled, this will be lowered to WebAssembly's memory.copy instruction.
9092 // This instruction will trap on an invalid address, regardless of the length.9090 // This instruction will trap on an invalid address, regardless of the length.
...@@ -9103,27 +9101,27 @@ pub const FuncGen = struct {...@@ -9103,27 +9101,27 @@ pub const FuncGen = struct {
9103 const end_block = try self.wip.block(2, "MemcpyTrapEnd");9101 const end_block = try self.wip.block(2, "MemcpyTrapEnd");
9104 _ = try self.wip.brCond(cond, memcpy_block, end_block);9102 _ = try self.wip.brCond(cond, memcpy_block, end_block);
9105 self.wip.cursor = .{ .block = memcpy_block };9103 self.wip.cursor = .{ .block = memcpy_block };
9106 _ = (try self.wip.unimplemented(.void, "")).finish(self.builder.buildMemCpy(9104 _ = try self.wip.callMemCpy(
9107 dest_ptr.toLlvm(&self.wip),9105 dest_ptr,
9108 dest_ptr_ty.ptrAlignment(mod),9106 Builder.Alignment.fromByteUnits(dest_ptr_ty.ptrAlignment(mod)),
9109 src_ptr.toLlvm(&self.wip),9107 src_ptr,
9110 src_ptr_ty.ptrAlignment(mod),9108 Builder.Alignment.fromByteUnits(src_ptr_ty.ptrAlignment(mod)),
9111 len.toLlvm(&self.wip),9109 len,
9112 is_volatile,9110 access_kind,
9113 ), &self.wip);9111 );
9114 _ = try self.wip.br(end_block);9112 _ = try self.wip.br(end_block);
9115 self.wip.cursor = .{ .block = end_block };9113 self.wip.cursor = .{ .block = end_block };
9116 return .none;9114 return .none;
9117 }9115 }
91189116
9119 _ = (try self.wip.unimplemented(.void, "")).finish(self.builder.buildMemCpy(9117 _ = try self.wip.callMemCpy(
9120 dest_ptr.toLlvm(&self.wip),9118 dest_ptr,
9121 dest_ptr_ty.ptrAlignment(mod),9119 Builder.Alignment.fromByteUnits(dest_ptr_ty.ptrAlignment(mod)),
9122 src_ptr.toLlvm(&self.wip),9120 src_ptr,
9123 src_ptr_ty.ptrAlignment(mod),9121 Builder.Alignment.fromByteUnits(src_ptr_ty.ptrAlignment(mod)),
9124 len.toLlvm(&self.wip),9122 len,
9125 is_volatile,9123 access_kind,
9126 ), &self.wip);9124 );
9127 return .none;9125 return .none;
9128 }9126 }
91299127
...@@ -9196,8 +9194,8 @@ pub const FuncGen = struct {...@@ -9196,8 +9194,8 @@ pub const FuncGen = struct {
9196 const operand_ty = self.typeOf(ty_op.operand);9194 const operand_ty = self.typeOf(ty_op.operand);
9197 const operand = try self.resolveInst(ty_op.operand);9195 const operand = try self.resolveInst(ty_op.operand);
91989196
9199 const result =9197 const result = try self.wip.callIntrinsic(
9200 try self.wip.callIntrinsic(9198 .none,
9201 intrinsic,9199 intrinsic,
9202 &.{try o.lowerType(operand_ty)},9200 &.{try o.lowerType(operand_ty)},
9203 &.{ operand, .false },9201 &.{ operand, .false },
...@@ -9214,6 +9212,7 @@ pub const FuncGen = struct {...@@ -9214,6 +9212,7 @@ pub const FuncGen = struct {
9214 const operand = try self.resolveInst(ty_op.operand);9212 const operand = try self.resolveInst(ty_op.operand);
92159213
9216 const result = try self.wip.callIntrinsic(9214 const result = try self.wip.callIntrinsic(
9215 .none,
9217 intrinsic,9216 intrinsic,
9218 &.{try o.lowerType(operand_ty)},9217 &.{try o.lowerType(operand_ty)},
9219 &.{operand},9218 &.{operand},
...@@ -9251,7 +9250,7 @@ pub const FuncGen = struct {...@@ -9251,7 +9250,7 @@ pub const FuncGen = struct {
9251 bits = bits + 8;9250 bits = bits + 8;
9252 }9251 }
92539252
9254 const result = try self.wip.callIntrinsic(.bswap, &.{llvm_operand_ty}, &.{operand}, "");9253 const result = try self.wip.callIntrinsic(.none, .bswap, &.{llvm_operand_ty}, &.{operand}, "");
9255 return self.wip.conv(.unsigned, result, try o.lowerType(inst_ty), "");9254 return self.wip.conv(.unsigned, result, try o.lowerType(inst_ty), "");
9256 }9255 }
92579256
...@@ -9646,14 +9645,14 @@ pub const FuncGen = struct {...@@ -9646,14 +9645,14 @@ pub const FuncGen = struct {
9646 const llvm_scalar_ty = try o.lowerType(scalar_ty);9645 const llvm_scalar_ty = try o.lowerType(scalar_ty);
96479646
9648 switch (reduce.operation) {9647 switch (reduce.operation) {
9649 .And, .Or, .Xor => return self.wip.callIntrinsic(switch (reduce.operation) {9648 .And, .Or, .Xor => return self.wip.callIntrinsic(.none, switch (reduce.operation) {
9650 .And => .@"vector.reduce.and",9649 .And => .@"vector.reduce.and",
9651 .Or => .@"vector.reduce.or",9650 .Or => .@"vector.reduce.or",
9652 .Xor => .@"vector.reduce.xor",9651 .Xor => .@"vector.reduce.xor",
9653 else => unreachable,9652 else => unreachable,
9654 }, &.{llvm_operand_ty}, &.{operand}, ""),9653 }, &.{llvm_operand_ty}, &.{operand}, ""),
9655 .Min, .Max => switch (scalar_ty.zigTypeTag(mod)) {9654 .Min, .Max => switch (scalar_ty.zigTypeTag(mod)) {
9656 .Int => return self.wip.callIntrinsic(switch (reduce.operation) {9655 .Int => return self.wip.callIntrinsic(.none, switch (reduce.operation) {
9657 .Min => if (scalar_ty.isSignedInt(mod))9656 .Min => if (scalar_ty.isSignedInt(mod))
9658 .@"vector.reduce.smin"9657 .@"vector.reduce.smin"
9659 else9658 else
...@@ -9665,7 +9664,7 @@ pub const FuncGen = struct {...@@ -9665,7 +9664,7 @@ pub const FuncGen = struct {
9665 else => unreachable,9664 else => unreachable,
9666 }, &.{llvm_operand_ty}, &.{operand}, ""),9665 }, &.{llvm_operand_ty}, &.{operand}, ""),
9667 .Float => if (intrinsicsAllowed(scalar_ty, target))9666 .Float => if (intrinsicsAllowed(scalar_ty, target))
9668 return self.wip.callIntrinsic(switch (reduce.operation) {9667 return self.wip.callIntrinsic(.none, switch (reduce.operation) {
9669 .Min => .@"vector.reduce.fmin",9668 .Min => .@"vector.reduce.fmin",
9670 .Max => .@"vector.reduce.fmax",9669 .Max => .@"vector.reduce.fmax",
9671 else => unreachable,9670 else => unreachable,
...@@ -9673,13 +9672,13 @@ pub const FuncGen = struct {...@@ -9673,13 +9672,13 @@ pub const FuncGen = struct {
9673 else => unreachable,9672 else => unreachable,
9674 },9673 },
9675 .Add, .Mul => switch (scalar_ty.zigTypeTag(mod)) {9674 .Add, .Mul => switch (scalar_ty.zigTypeTag(mod)) {
9676 .Int => return self.wip.callIntrinsic(switch (reduce.operation) {9675 .Int => return self.wip.callIntrinsic(.none, switch (reduce.operation) {
9677 .Add => .@"vector.reduce.add",9676 .Add => .@"vector.reduce.add",
9678 .Mul => .@"vector.reduce.mul",9677 .Mul => .@"vector.reduce.mul",
9679 else => unreachable,9678 else => unreachable,
9680 }, &.{llvm_operand_ty}, &.{operand}, ""),9679 }, &.{llvm_operand_ty}, &.{operand}, ""),
9681 .Float => if (intrinsicsAllowed(scalar_ty, target))9680 .Float => if (intrinsicsAllowed(scalar_ty, target))
9682 return self.wip.callIntrinsic(switch (reduce.operation) {9681 return self.wip.callIntrinsic(.none, switch (reduce.operation) {
9683 .Add => .@"vector.reduce.fadd",9682 .Add => .@"vector.reduce.fadd",
9684 .Mul => .@"vector.reduce.fmul",9683 .Mul => .@"vector.reduce.fmul",
9685 else => unreachable,9684 else => unreachable,
...@@ -10032,7 +10031,7 @@ pub const FuncGen = struct {...@@ -10032,7 +10031,7 @@ pub const FuncGen = struct {
10032 .data => {},10031 .data => {},
10033 }10032 }
1003410033
10035 _ = try self.wip.callIntrinsic(.prefetch, &.{.ptr}, &.{10034 _ = try self.wip.callIntrinsic(.none, .prefetch, &.{.ptr}, &.{
10036 try self.resolveInst(prefetch.ptr),10035 try self.resolveInst(prefetch.ptr),
10037 try o.builder.intValue(.i32, prefetch.rw),10036 try o.builder.intValue(.i32, prefetch.rw),
10038 try o.builder.intValue(.i32, prefetch.locality),10037 try o.builder.intValue(.i32, prefetch.locality),
...@@ -10056,14 +10055,12 @@ pub const FuncGen = struct {...@@ -10056,14 +10055,12 @@ pub const FuncGen = struct {
10056 default: u32,10055 default: u32,
10057 comptime basename: []const u8,10056 comptime basename: []const u8,
10058 ) !Builder.Value {10057 ) !Builder.Value {
10059 const o = self.dg.object;10058 return self.wip.callIntrinsic(.none, switch (dimension) {
10060 const intrinsic = switch (dimension) {
10061 0 => @field(Builder.Intrinsic, basename ++ ".x"),10059 0 => @field(Builder.Intrinsic, basename ++ ".x"),
10062 1 => @field(Builder.Intrinsic, basename ++ ".y"),10060 1 => @field(Builder.Intrinsic, basename ++ ".y"),
10063 2 => @field(Builder.Intrinsic, basename ++ ".z"),10061 2 => @field(Builder.Intrinsic, basename ++ ".z"),
10064 else => return o.builder.intValue(.i32, default),10062 else => return self.dg.object.builder.intValue(.i32, default),
10065 };10063 }, &.{}, &.{}, "");
10066 return self.wip.callIntrinsic(intrinsic, &.{}, &.{}, "");
10067 }10064 }
1006810065
10069 fn airWorkItemId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {10066 fn airWorkItemId(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
...@@ -10087,7 +10084,7 @@ pub const FuncGen = struct {...@@ -10087,7 +10084,7 @@ pub const FuncGen = struct {
1008710084
10088 // Fetch the dispatch pointer, which points to this structure:10085 // Fetch the dispatch pointer, which points to this structure:
10089 // https://github.com/RadeonOpenCompute/ROCR-Runtime/blob/adae6c61e10d371f7cbc3d0e94ae2c070cab18a4/src/inc/hsa.h#L291310086 // https://github.com/RadeonOpenCompute/ROCR-Runtime/blob/adae6c61e10d371f7cbc3d0e94ae2c070cab18a4/src/inc/hsa.h#L2913
10090 const dispatch_ptr = try self.wip.callIntrinsic(.@"amdgcn.dispatch.ptr", &.{}, &.{}, "");10087 const dispatch_ptr = try self.wip.callIntrinsic(.none, .@"amdgcn.dispatch.ptr", &.{}, &.{}, "");
1009110088
10092 // Load the work_group_* member from the struct as u16.10089 // Load the work_group_* member from the struct as u16.
10093 // Just treat the dispatch pointer as an array of u16 to keep things simple.10090 // Just treat the dispatch pointer as an array of u16 to keep things simple.
...@@ -10188,7 +10185,7 @@ pub const FuncGen = struct {...@@ -10188,7 +10185,7 @@ pub const FuncGen = struct {
10188 if (can_elide_load)10185 if (can_elide_load)
10189 return payload_ptr;10186 return payload_ptr;
1019010187
10191 return fg.loadByRef(payload_ptr, payload_ty, payload_alignment, false);10188 return fg.loadByRef(payload_ptr, payload_ty, payload_alignment, .normal);
10192 }10189 }
10193 const payload_llvm_ty = try o.lowerType(payload_ty);10190 const payload_llvm_ty = try o.lowerType(payload_ty);
10194 return fg.wip.load(.normal, payload_llvm_ty, payload_ptr, payload_alignment, "");10191 return fg.wip.load(.normal, payload_llvm_ty, payload_ptr, payload_alignment, "");
...@@ -10297,7 +10294,7 @@ pub const FuncGen = struct {...@@ -10297,7 +10294,7 @@ pub const FuncGen = struct {
10297 ptr: Builder.Value,10294 ptr: Builder.Value,
10298 pointee_type: Type,10295 pointee_type: Type,
10299 ptr_alignment: Builder.Alignment,10296 ptr_alignment: Builder.Alignment,
10300 is_volatile: bool,10297 access_kind: Builder.MemoryAccessKind,
10301 ) !Builder.Value {10298 ) !Builder.Value {
10302 const o = fg.dg.object;10299 const o = fg.dg.object;
10303 const mod = o.module;10300 const mod = o.module;
...@@ -10306,16 +10303,15 @@ pub const FuncGen = struct {...@@ -10306,16 +10303,15 @@ pub const FuncGen = struct {
10306 @max(ptr_alignment.toByteUnits() orelse 0, pointee_type.abiAlignment(mod)),10303 @max(ptr_alignment.toByteUnits() orelse 0, pointee_type.abiAlignment(mod)),
10307 );10304 );
10308 const result_ptr = try fg.buildAlloca(pointee_llvm_ty, result_align);10305 const result_ptr = try fg.buildAlloca(pointee_llvm_ty, result_align);
10309 const usize_ty = try o.lowerType(Type.usize);
10310 const size_bytes = pointee_type.abiSize(mod);10306 const size_bytes = pointee_type.abiSize(mod);
10311 _ = (try fg.wip.unimplemented(.void, "")).finish(fg.builder.buildMemCpy(10307 _ = try fg.wip.callMemCpy(
10312 result_ptr.toLlvm(&fg.wip),10308 result_ptr,
10313 @intCast(result_align.toByteUnits() orelse 0),10309 result_align,
10314 ptr.toLlvm(&fg.wip),10310 ptr,
10315 @intCast(ptr_alignment.toByteUnits() orelse 0),10311 ptr_alignment,
10316 (try o.builder.intConst(usize_ty, size_bytes)).toLlvm(&o.builder),10312 try o.builder.intValue(try o.lowerType(Type.usize), size_bytes),
10317 is_volatile,10313 access_kind,
10318 ), &fg.wip);10314 );
10319 return result_ptr;10315 return result_ptr;
10320 }10316 }
1032110317
...@@ -10332,10 +10328,8 @@ pub const FuncGen = struct {...@@ -10332,10 +10328,8 @@ pub const FuncGen = struct {
10332 const ptr_alignment = Builder.Alignment.fromByteUnits(10328 const ptr_alignment = Builder.Alignment.fromByteUnits(
10333 info.flags.alignment.toByteUnitsOptional() orelse elem_ty.abiAlignment(mod),10329 info.flags.alignment.toByteUnitsOptional() orelse elem_ty.abiAlignment(mod),
10334 );10330 );
10335 const ptr_kind: Builder.MemoryAccessKind = switch (info.flags.is_volatile) {10331 const access_kind: Builder.MemoryAccessKind =
10336 false => .normal,10332 if (info.flags.is_volatile) .@"volatile" else .normal;
10337 true => .@"volatile",
10338 };
1033910333
10340 assert(info.flags.vector_index != .runtime);10334 assert(info.flags.vector_index != .runtime);
10341 if (info.flags.vector_index != .none) {10335 if (info.flags.vector_index != .none) {
...@@ -10343,19 +10337,20 @@ pub const FuncGen = struct {...@@ -10343,19 +10337,20 @@ pub const FuncGen = struct {
10343 const vec_elem_ty = try o.lowerType(elem_ty);10337 const vec_elem_ty = try o.lowerType(elem_ty);
10344 const vec_ty = try o.builder.vectorType(.normal, info.packed_offset.host_size, vec_elem_ty);10338 const vec_ty = try o.builder.vectorType(.normal, info.packed_offset.host_size, vec_elem_ty);
1034510339
10346 const loaded_vector = try self.wip.load(ptr_kind, vec_ty, ptr, ptr_alignment, "");10340 const loaded_vector = try self.wip.load(access_kind, vec_ty, ptr, ptr_alignment, "");
10347 return self.wip.extractElement(loaded_vector, index_u32, "");10341 return self.wip.extractElement(loaded_vector, index_u32, "");
10348 }10342 }
1034910343
10350 if (info.packed_offset.host_size == 0) {10344 if (info.packed_offset.host_size == 0) {
10351 if (isByRef(elem_ty, mod)) {10345 if (isByRef(elem_ty, mod)) {
10352 return self.loadByRef(ptr, elem_ty, ptr_alignment, info.flags.is_volatile);10346 return self.loadByRef(ptr, elem_ty, ptr_alignment, access_kind);
10353 }10347 }
10354 return self.wip.load(ptr_kind, try o.lowerType(elem_ty), ptr, ptr_alignment, "");10348 return self.wip.load(access_kind, try o.lowerType(elem_ty), ptr, ptr_alignment, "");
10355 }10349 }
1035610350
10357 const containing_int_ty = try o.builder.intType(@intCast(info.packed_offset.host_size * 8));10351 const containing_int_ty = try o.builder.intType(@intCast(info.packed_offset.host_size * 8));
10358 const containing_int = try self.wip.load(ptr_kind, containing_int_ty, ptr, ptr_alignment, "");10352 const containing_int =
10353 try self.wip.load(access_kind, containing_int_ty, ptr, ptr_alignment, "");
1035910354
10360 const elem_bits = ptr_ty.childType(mod).bitSize(mod);10355 const elem_bits = ptr_ty.childType(mod).bitSize(mod);
10361 const shift_amt = try o.builder.intValue(containing_int_ty, info.packed_offset.bit_offset);10356 const shift_amt = try o.builder.intValue(containing_int_ty, info.packed_offset.bit_offset);
...@@ -10402,10 +10397,8 @@ pub const FuncGen = struct {...@@ -10402,10 +10397,8 @@ pub const FuncGen = struct {
10402 return;10397 return;
10403 }10398 }
10404 const ptr_alignment = Builder.Alignment.fromByteUnits(ptr_ty.ptrAlignment(mod));10399 const ptr_alignment = Builder.Alignment.fromByteUnits(ptr_ty.ptrAlignment(mod));
10405 const ptr_kind: Builder.MemoryAccessKind = switch (info.flags.is_volatile) {10400 const access_kind: Builder.MemoryAccessKind =
10406 false => .normal,10401 if (info.flags.is_volatile) .@"volatile" else .normal;
10407 true => .@"volatile",
10408 };
1040910402
10410 assert(info.flags.vector_index != .runtime);10403 assert(info.flags.vector_index != .runtime);
10411 if (info.flags.vector_index != .none) {10404 if (info.flags.vector_index != .none) {
...@@ -10413,12 +10406,12 @@ pub const FuncGen = struct {...@@ -10413,12 +10406,12 @@ pub const FuncGen = struct {
10413 const vec_elem_ty = try o.lowerType(elem_ty);10406 const vec_elem_ty = try o.lowerType(elem_ty);
10414 const vec_ty = try o.builder.vectorType(.normal, info.packed_offset.host_size, vec_elem_ty);10407 const vec_ty = try o.builder.vectorType(.normal, info.packed_offset.host_size, vec_elem_ty);
1041510408
10416 const loaded_vector = try self.wip.load(ptr_kind, vec_ty, ptr, ptr_alignment, "");10409 const loaded_vector = try self.wip.load(access_kind, vec_ty, ptr, ptr_alignment, "");
1041710410
10418 const modified_vector = try self.wip.insertElement(loaded_vector, elem, index_u32, "");10411 const modified_vector = try self.wip.insertElement(loaded_vector, elem, index_u32, "");
1041910412
10420 assert(ordering == .none);10413 assert(ordering == .none);
10421 _ = try self.wip.store(ptr_kind, modified_vector, ptr, ptr_alignment);10414 _ = try self.wip.store(access_kind, modified_vector, ptr, ptr_alignment);
10422 return;10415 return;
10423 }10416 }
1042410417
...@@ -10426,7 +10419,7 @@ pub const FuncGen = struct {...@@ -10426,7 +10419,7 @@ pub const FuncGen = struct {
10426 const containing_int_ty = try o.builder.intType(@intCast(info.packed_offset.host_size * 8));10419 const containing_int_ty = try o.builder.intType(@intCast(info.packed_offset.host_size * 8));
10427 assert(ordering == .none);10420 assert(ordering == .none);
10428 const containing_int =10421 const containing_int =
10429 try self.wip.load(ptr_kind, containing_int_ty, ptr, ptr_alignment, "");10422 try self.wip.load(access_kind, containing_int_ty, ptr, ptr_alignment, "");
10430 const elem_bits = ptr_ty.childType(mod).bitSize(mod);10423 const elem_bits = ptr_ty.childType(mod).bitSize(mod);
10431 const shift_amt = try o.builder.intConst(containing_int_ty, info.packed_offset.bit_offset);10424 const shift_amt = try o.builder.intConst(containing_int_ty, info.packed_offset.bit_offset);
10432 // Convert to equally-sized integer type in order to perform the bit10425 // Convert to equally-sized integer type in order to perform the bit
...@@ -10450,23 +10443,29 @@ pub const FuncGen = struct {...@@ -10450,23 +10443,29 @@ pub const FuncGen = struct {
10450 const ored_value = try self.wip.bin(.@"or", shifted_value, anded_containing_int, "");10443 const ored_value = try self.wip.bin(.@"or", shifted_value, anded_containing_int, "");
1045110444
10452 assert(ordering == .none);10445 assert(ordering == .none);
10453 _ = try self.wip.store(ptr_kind, ored_value, ptr, ptr_alignment);10446 _ = try self.wip.store(access_kind, ored_value, ptr, ptr_alignment);
10454 return;10447 return;
10455 }10448 }
10456 if (!isByRef(elem_ty, mod)) {10449 if (!isByRef(elem_ty, mod)) {
10457 _ = try self.wip.storeAtomic(ptr_kind, elem, ptr, self.sync_scope, ordering, ptr_alignment);10450 _ = try self.wip.storeAtomic(
10451 access_kind,
10452 elem,
10453 ptr,
10454 self.sync_scope,
10455 ordering,
10456 ptr_alignment,
10457 );
10458 return;10458 return;
10459 }10459 }
10460 assert(ordering == .none);10460 assert(ordering == .none);
10461 const size_bytes = elem_ty.abiSize(mod);10461 _ = try self.wip.callMemCpy(
10462 _ = (try self.wip.unimplemented(.void, "")).finish(self.builder.buildMemCpy(10462 ptr,
10463 ptr.toLlvm(&self.wip),10463 ptr_alignment,
10464 @intCast(ptr_alignment.toByteUnits() orelse 0),10464 elem,
10465 elem.toLlvm(&self.wip),10465 Builder.Alignment.fromByteUnits(elem_ty.abiAlignment(mod)),
10466 elem_ty.abiAlignment(mod),10466 try o.builder.intValue(try o.lowerType(Type.usize), elem_ty.abiSize(mod)),
10467 (try o.builder.intConst(try o.lowerType(Type.usize), size_bytes)).toLlvm(&o.builder),10467 access_kind,
10468 info.flags.is_volatile,10468 );
10469 ), &self.wip);
10470 }10469 }
1047110470
10472 fn valgrindMarkUndef(fg: *FuncGen, ptr: Builder.Value, len: Builder.Value) Allocator.Error!void {10471 fn valgrindMarkUndef(fg: *FuncGen, ptr: Builder.Value, len: Builder.Value) Allocator.Error!void {
src/codegen/llvm/Builder.zig+333-13
...@@ -2397,7 +2397,7 @@ pub const Intrinsic = enum {...@@ -2397,7 +2397,7 @@ pub const Intrinsic = enum {
2397 @"udiv.fix.sat",2397 @"udiv.fix.sat",
23982398
2399 // Specialised Arithmetic2399 // Specialised Arithmetic
2400 canonicalisze,2400 canonicalize,
2401 fmuladd,2401 fmuladd,
24022402
2403 // Vector Reduction2403 // Vector Reduction
...@@ -2416,14 +2416,15 @@ pub const Intrinsic = enum {...@@ -2416,14 +2416,15 @@ pub const Intrinsic = enum {
2416 @"vector.reduce.fmin",2416 @"vector.reduce.fmin",
2417 @"vector.reduce.fmaximum",2417 @"vector.reduce.fmaximum",
2418 @"vector.reduce.fminimum",2418 @"vector.reduce.fminimum",
2419 @"vector.reduce.insert",
2420 @"vector.reduce.extract",
2421 @"vector.insert",2419 @"vector.insert",
2422 @"vector.extract",2420 @"vector.extract",
24232421
2422 // Floating-Point Test
2423 @"is.fpclass",
2424
2424 // General2425 // General
2425 @"llvm.var.annotation",2426 @"var.annotation",
2426 @"llvm.ptr.annotation",2427 @"ptr.annotation",
2427 annotation,2428 annotation,
2428 @"codeview.annotation",2429 @"codeview.annotation",
2429 trap,2430 trap,
...@@ -2442,7 +2443,7 @@ pub const Intrinsic = enum {...@@ -2442,7 +2443,7 @@ pub const Intrinsic = enum {
2442 @"arithmetic.fence",2443 @"arithmetic.fence",
2443 donothing,2444 donothing,
2444 @"load.relative",2445 @"load.relative",
2445 @"llvm.sideeffect",2446 sideeffect,
2446 @"is.constant",2447 @"is.constant",
2447 ptrmask,2448 ptrmask,
2448 @"threadlocal.address",2449 @"threadlocal.address",
...@@ -2483,10 +2484,7 @@ pub const Intrinsic = enum {...@@ -2483,10 +2484,7 @@ pub const Intrinsic = enum {
2483 };2484 };
2484 };2485 };
24852486
2486 const signatures = std.enums.EnumArray(Intrinsic, Signature).initDefault(.{2487 const signatures = std.enums.EnumArray(Intrinsic, Signature).init(.{
2487 .ret_len = 0,
2488 .params = &.{},
2489 }, .{
2490 .va_start = .{2488 .va_start = .{
2491 .ret_len = 0,2489 .ret_len = 0,
2492 .params = &.{2490 .params = &.{
...@@ -2603,6 +2601,56 @@ pub const Intrinsic = enum {...@@ -2603,6 +2601,56 @@ pub const Intrinsic = enum {
2603 },2601 },
2604 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },2602 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2605 },2603 },
2604 .memcpy = .{
2605 .ret_len = 0,
2606 .params = &.{
2607 .{ .kind = .overloaded, .attrs = &.{ .@"noalias", .nocapture, .writeonly } },
2608 .{ .kind = .overloaded, .attrs = &.{ .@"noalias", .nocapture, .readonly } },
2609 .{ .kind = .overloaded },
2610 .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} },
2611 },
2612 .attrs = &.{ .nocallback, .nofree, .nounwind, .willreturn, .{ .memory = .{ .argmem = .readwrite } } },
2613 },
2614 .@"memcpy.inline" = .{
2615 .ret_len = 0,
2616 .params = &.{
2617 .{ .kind = .overloaded, .attrs = &.{ .@"noalias", .nocapture, .writeonly } },
2618 .{ .kind = .overloaded, .attrs = &.{ .@"noalias", .nocapture, .readonly } },
2619 .{ .kind = .overloaded, .attrs = &.{.immarg} },
2620 .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} },
2621 },
2622 .attrs = &.{ .nocallback, .nofree, .nounwind, .willreturn, .{ .memory = .{ .argmem = .readwrite } } },
2623 },
2624 .memmove = .{
2625 .ret_len = 0,
2626 .params = &.{
2627 .{ .kind = .overloaded, .attrs = &.{ .nocapture, .writeonly } },
2628 .{ .kind = .overloaded, .attrs = &.{ .nocapture, .readonly } },
2629 .{ .kind = .overloaded },
2630 .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} },
2631 },
2632 .attrs = &.{ .nocallback, .nofree, .nounwind, .willreturn, .{ .memory = .{ .argmem = .readwrite } } },
2633 },
2634 .memset = .{
2635 .ret_len = 0,
2636 .params = &.{
2637 .{ .kind = .overloaded, .attrs = &.{ .nocapture, .writeonly } },
2638 .{ .kind = .{ .type = .i8 } },
2639 .{ .kind = .overloaded },
2640 .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} },
2641 },
2642 .attrs = &.{ .nocallback, .nofree, .nounwind, .willreturn, .{ .memory = .{ .argmem = .write } } },
2643 },
2644 .@"memset.inline" = .{
2645 .ret_len = 0,
2646 .params = &.{
2647 .{ .kind = .overloaded, .attrs = &.{ .nocapture, .writeonly } },
2648 .{ .kind = .{ .type = .i8 } },
2649 .{ .kind = .overloaded, .attrs = &.{.immarg} },
2650 .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} },
2651 },
2652 .attrs = &.{ .nocallback, .nofree, .nounwind, .willreturn, .{ .memory = .{ .argmem = .write } } },
2653 },
2606 .sqrt = .{2654 .sqrt = .{
2607 .ret_len = 1,2655 .ret_len = 1,
2608 .params = &.{2656 .params = &.{
...@@ -2884,7 +2932,7 @@ pub const Intrinsic = enum {...@@ -2884,7 +2932,7 @@ pub const Intrinsic = enum {
2884 .params = &.{2932 .params = &.{
2885 .{ .kind = .overloaded },2933 .{ .kind = .overloaded },
2886 .{ .kind = .{ .matches = 0 } },2934 .{ .kind = .{ .matches = 0 } },
2887 .{ .kind = .{ .type = .i1 } },2935 .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} },
2888 },2936 },
2889 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },2937 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2890 },2938 },
...@@ -2893,7 +2941,7 @@ pub const Intrinsic = enum {...@@ -2893,7 +2941,7 @@ pub const Intrinsic = enum {
2893 .params = &.{2941 .params = &.{
2894 .{ .kind = .overloaded },2942 .{ .kind = .overloaded },
2895 .{ .kind = .{ .matches = 0 } },2943 .{ .kind = .{ .matches = 0 } },
2896 .{ .kind = .{ .type = .i1 } },2944 .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} },
2897 },2945 },
2898 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },2946 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
2899 },2947 },
...@@ -3115,6 +3163,25 @@ pub const Intrinsic = enum {...@@ -3115,6 +3163,25 @@ pub const Intrinsic = enum {
3115 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3163 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3116 },3164 },
31173165
3166 .canonicalize = .{
3167 .ret_len = 1,
3168 .params = &.{
3169 .{ .kind = .overloaded },
3170 .{ .kind = .{ .matches = 0 } },
3171 },
3172 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3173 },
3174 .fmuladd = .{
3175 .ret_len = 1,
3176 .params = &.{
3177 .{ .kind = .overloaded },
3178 .{ .kind = .{ .matches = 0 } },
3179 .{ .kind = .{ .matches = 0 } },
3180 .{ .kind = .{ .matches = 0 } },
3181 },
3182 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3183 },
3184
3118 .@"vector.reduce.add" = .{3185 .@"vector.reduce.add" = .{
3119 .ret_len = 1,3186 .ret_len = 1,
3120 .params = &.{3187 .params = &.{
...@@ -3257,6 +3324,57 @@ pub const Intrinsic = enum {...@@ -3257,6 +3324,57 @@ pub const Intrinsic = enum {
3257 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },3324 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3258 },3325 },
32593326
3327 .@"is.fpclass" = .{
3328 .ret_len = 1,
3329 .params = &.{
3330 .{ .kind = .{ .matches_changed_scalar = .{ .index = 1, .scalar = .i1 } } },
3331 .{ .kind = .overloaded },
3332 .{ .kind = .{ .type = .i32 }, .attrs = &.{.immarg} },
3333 },
3334 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3335 },
3336
3337 .@"var.annotation" = .{
3338 .ret_len = 0,
3339 .params = &.{
3340 .{ .kind = .overloaded },
3341 .{ .kind = .overloaded },
3342 .{ .kind = .{ .matches = 1 } },
3343 .{ .kind = .{ .type = .i32 } },
3344 .{ .kind = .{ .matches = 1 } },
3345 },
3346 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .{ .inaccessiblemem = .readwrite } } },
3347 },
3348 .@"ptr.annotation" = .{
3349 .ret_len = 1,
3350 .params = &.{
3351 .{ .kind = .overloaded },
3352 .{ .kind = .{ .matches = 0 } },
3353 .{ .kind = .overloaded },
3354 .{ .kind = .{ .matches = 2 } },
3355 .{ .kind = .{ .type = .i32 } },
3356 .{ .kind = .{ .matches = 2 } },
3357 },
3358 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .{ .inaccessiblemem = .readwrite } } },
3359 },
3360 .annotation = .{
3361 .ret_len = 1,
3362 .params = &.{
3363 .{ .kind = .overloaded },
3364 .{ .kind = .{ .matches = 0 } },
3365 .{ .kind = .overloaded },
3366 .{ .kind = .{ .matches = 2 } },
3367 .{ .kind = .{ .type = .i32 } },
3368 },
3369 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .{ .inaccessiblemem = .readwrite } } },
3370 },
3371 .@"codeview.annotation" = .{
3372 .ret_len = 0,
3373 .params = &.{
3374 .{ .kind = .{ .type = .metadata } },
3375 },
3376 .attrs = &.{ .nocallback, .noduplicate, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .{ .inaccessiblemem = .readwrite } } },
3377 },
3260 .trap = .{3378 .trap = .{
3261 .ret_len = 0,3379 .ret_len = 0,
3262 .params = &.{},3380 .params = &.{},
...@@ -3274,6 +3392,156 @@ pub const Intrinsic = enum {...@@ -3274,6 +3392,156 @@ pub const Intrinsic = enum {
3274 },3392 },
3275 .attrs = &.{ .cold, .noreturn, .nounwind },3393 .attrs = &.{ .cold, .noreturn, .nounwind },
3276 },3394 },
3395 .stackprotector = .{
3396 .ret_len = 0,
3397 .params = &.{
3398 .{ .kind = .{ .type = .ptr } },
3399 .{ .kind = .{ .type = .ptr } },
3400 },
3401 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn },
3402 },
3403 .stackguard = .{
3404 .ret_len = 1,
3405 .params = &.{
3406 .{ .kind = .{ .type = .ptr } },
3407 },
3408 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn },
3409 },
3410 .objectsize = .{
3411 .ret_len = 1,
3412 .params = &.{
3413 .{ .kind = .overloaded },
3414 .{ .kind = .overloaded },
3415 .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} },
3416 .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} },
3417 .{ .kind = .{ .type = .i1 }, .attrs = &.{.immarg} },
3418 },
3419 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3420 },
3421 .expect = .{
3422 .ret_len = 1,
3423 .params = &.{
3424 .{ .kind = .overloaded },
3425 .{ .kind = .{ .matches = 0 } },
3426 .{ .kind = .{ .matches = 0 } },
3427 },
3428 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3429 },
3430 .@"expect.with.probability" = .{
3431 .ret_len = 1,
3432 .params = &.{
3433 .{ .kind = .overloaded },
3434 .{ .kind = .{ .matches = 0 } },
3435 .{ .kind = .{ .matches = 0 } },
3436 .{ .kind = .{ .type = .double }, .attrs = &.{.immarg} },
3437 },
3438 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3439 },
3440 .assume = .{
3441 .ret_len = 0,
3442 .params = &.{
3443 .{ .kind = .{ .type = .i1 }, .attrs = &.{.noundef} },
3444 },
3445 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .{ .inaccessiblemem = .write } } },
3446 },
3447 .@"ssa.copy" = .{
3448 .ret_len = 1,
3449 .params = &.{
3450 .{ .kind = .overloaded },
3451 .{ .kind = .{ .matches = 0 }, .attrs = &.{.returned} },
3452 },
3453 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3454 },
3455 .@"type.test" = .{
3456 .ret_len = 1,
3457 .params = &.{
3458 .{ .kind = .{ .type = .i1 } },
3459 .{ .kind = .{ .type = .ptr } },
3460 .{ .kind = .{ .type = .metadata } },
3461 },
3462 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3463 },
3464 .@"type.checked.load" = .{
3465 .ret_len = 2,
3466 .params = &.{
3467 .{ .kind = .{ .type = .ptr } },
3468 .{ .kind = .{ .type = .i1 } },
3469 .{ .kind = .{ .type = .ptr } },
3470 .{ .kind = .{ .type = .i32 } },
3471 .{ .kind = .{ .type = .metadata } },
3472 },
3473 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3474 },
3475 .@"type.checked.load.relative" = .{
3476 .ret_len = 2,
3477 .params = &.{
3478 .{ .kind = .{ .type = .ptr } },
3479 .{ .kind = .{ .type = .i1 } },
3480 .{ .kind = .{ .type = .ptr } },
3481 .{ .kind = .{ .type = .i32 } },
3482 .{ .kind = .{ .type = .metadata } },
3483 },
3484 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3485 },
3486 .@"arithmetic.fence" = .{
3487 .ret_len = 1,
3488 .params = &.{
3489 .{ .kind = .overloaded },
3490 .{ .kind = .{ .matches = 0 } },
3491 },
3492 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3493 },
3494 .donothing = .{
3495 .ret_len = 0,
3496 .params = &.{},
3497 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3498 },
3499 .@"load.relative" = .{
3500 .ret_len = 1,
3501 .params = &.{
3502 .{ .kind = .{ .type = .ptr } },
3503 .{ .kind = .{ .type = .ptr } },
3504 .{ .kind = .overloaded },
3505 },
3506 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .{ .argmem = .read } } },
3507 },
3508 .sideeffect = .{
3509 .ret_len = 0,
3510 .params = &.{},
3511 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = .{ .inaccessiblemem = .readwrite } } },
3512 },
3513 .@"is.constant" = .{
3514 .ret_len = 1,
3515 .params = &.{
3516 .{ .kind = .{ .type = .i1 } },
3517 .{ .kind = .overloaded },
3518 },
3519 .attrs = &.{ .convergent, .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3520 },
3521 .ptrmask = .{
3522 .ret_len = 1,
3523 .params = &.{
3524 .{ .kind = .overloaded },
3525 .{ .kind = .{ .matches = 0 } },
3526 .{ .kind = .overloaded },
3527 },
3528 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3529 },
3530 .@"threadlocal.address" = .{
3531 .ret_len = 1,
3532 .params = &.{
3533 .{ .kind = .overloaded, .attrs = &.{.nonnull} },
3534 .{ .kind = .{ .matches = 0 }, .attrs = &.{.nonnull} },
3535 },
3536 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .speculatable, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3537 },
3538 .vscale = .{
3539 .ret_len = 1,
3540 .params = &.{
3541 .{ .kind = .overloaded },
3542 },
3543 .attrs = &.{ .nocallback, .nofree, .nosync, .nounwind, .willreturn, .{ .memory = Attribute.Memory.all(.none) } },
3544 },
32773545
3278 .@"amdgcn.workitem.id.x" = .{3546 .@"amdgcn.workitem.id.x" = .{
3279 .ret_len = 1,3547 .ret_len = 1,
...@@ -5391,6 +5659,7 @@ pub const WipFunction = struct {...@@ -5391,6 +5659,7 @@ pub const WipFunction = struct {
53915659
5392 pub fn callIntrinsic(5660 pub fn callIntrinsic(
5393 self: *WipFunction,5661 self: *WipFunction,
5662 function_attributes: FunctionAttributes,
5394 id: Intrinsic,5663 id: Intrinsic,
5395 overload: []const Type,5664 overload: []const Type,
5396 args: []const Value,5665 args: []const Value,
...@@ -5400,7 +5669,7 @@ pub const WipFunction = struct {...@@ -5400,7 +5669,7 @@ pub const WipFunction = struct {
5400 return self.call(5669 return self.call(
5401 .normal,5670 .normal,
5402 CallConv.default,5671 CallConv.default,
5403 .none,5672 function_attributes,
5404 intrinsic.typeOf(self.builder),5673 intrinsic.typeOf(self.builder),
5405 intrinsic.toValue(self.builder),5674 intrinsic.toValue(self.builder),
5406 args,5675 args,
...@@ -5408,6 +5677,57 @@ pub const WipFunction = struct {...@@ -5408,6 +5677,57 @@ pub const WipFunction = struct {
5408 );5677 );
5409 }5678 }
54105679
5680 pub fn callMemCpy(
5681 self: *WipFunction,
5682 dst: Value,
5683 dst_align: Alignment,
5684 src: Value,
5685 src_align: Alignment,
5686 len: Value,
5687 kind: MemoryAccessKind,
5688 ) Allocator.Error!Instruction.Index {
5689 var dst_attrs = [_]Attribute.Index{try self.builder.attr(.{ .@"align" = dst_align })};
5690 var src_attrs = [_]Attribute.Index{try self.builder.attr(.{ .@"align" = src_align })};
5691 const value = try self.callIntrinsic(
5692 try self.builder.fnAttrs(&.{
5693 .none,
5694 .none,
5695 try self.builder.attrs(&dst_attrs),
5696 try self.builder.attrs(&src_attrs),
5697 }),
5698 .memcpy,
5699 &.{ dst.typeOfWip(self), src.typeOfWip(self), len.typeOfWip(self) },
5700 &.{ dst, src, len, switch (kind) {
5701 .normal => Value.false,
5702 .@"volatile" => Value.true,
5703 } },
5704 undefined,
5705 );
5706 return value.unwrap().instruction;
5707 }
5708
5709 pub fn callMemSet(
5710 self: *WipFunction,
5711 dst: Value,
5712 dst_align: Alignment,
5713 val: Value,
5714 len: Value,
5715 kind: MemoryAccessKind,
5716 ) Allocator.Error!Instruction.Index {
5717 var dst_attrs = [_]Attribute.Index{try self.builder.attr(.{ .@"align" = dst_align })};
5718 const value = try self.callIntrinsic(
5719 try self.builder.fnAttrs(&.{ .none, .none, try self.builder.attrs(&dst_attrs) }),
5720 .memset,
5721 &.{ dst.typeOfWip(self), len.typeOfWip(self) },
5722 &.{ dst, val, len, switch (kind) {
5723 .normal => Value.false,
5724 .@"volatile" => Value.true,
5725 } },
5726 undefined,
5727 );
5728 return value.unwrap().instruction;
5729 }
5730
5411 pub fn vaArg(self: *WipFunction, list: Value, ty: Type, name: []const u8) Allocator.Error!Value {5731 pub fn vaArg(self: *WipFunction, list: Value, ty: Type, name: []const u8) Allocator.Error!Value {
5412 try self.ensureUnusedExtraCapacity(1, Instruction.VaArg, 0);5732 try self.ensureUnusedExtraCapacity(1, Instruction.VaArg, 0);
5413 const instruction = try self.addInst(name, .{5733 const instruction = try self.addInst(name, .{
src/codegen/llvm/bindings.zig-21
...@@ -951,27 +951,6 @@ pub const Builder = opaque {...@@ -951,27 +951,6 @@ pub const Builder = opaque {
951 Name: [*:0]const u8,951 Name: [*:0]const u8,
952 ) *Value;952 ) *Value;
953953
954 pub const buildMemSet = ZigLLVMBuildMemSet;
955 extern fn ZigLLVMBuildMemSet(
956 B: *Builder,
957 Ptr: *Value,
958 Val: *Value,
959 Len: *Value,
960 Align: c_uint,
961 is_volatile: bool,
962 ) *Value;
963
964 pub const buildMemCpy = ZigLLVMBuildMemCpy;
965 extern fn ZigLLVMBuildMemCpy(
966 B: *Builder,
967 Dst: *Value,
968 DstAlign: c_uint,
969 Src: *Value,
970 SrcAlign: c_uint,
971 Size: *Value,
972 is_volatile: bool,
973 ) *Value;
974
975 pub const buildExactUDiv = LLVMBuildExactUDiv;954 pub const buildExactUDiv = LLVMBuildExactUDiv;
976 extern fn LLVMBuildExactUDiv(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;955 extern fn LLVMBuildExactUDiv(*Builder, LHS: *Value, RHS: *Value, Name: [*:0]const u8) *Value;
977956
src/value.zig+2-2
...@@ -3831,7 +3831,7 @@ pub const Value = struct {...@@ -3831,7 +3831,7 @@ pub const Value = struct {
38313831
3832 /// If the value is represented in-memory as a series of bytes that all3832 /// If the value is represented in-memory as a series of bytes that all
3833 /// have the same value, return that byte value, otherwise null.3833 /// have the same value, return that byte value, otherwise null.
3834 pub fn hasRepeatedByteRepr(val: Value, ty: Type, mod: *Module) !?Value {3834 pub fn hasRepeatedByteRepr(val: Value, ty: Type, mod: *Module) !?u8 {
3835 const abi_size = std.math.cast(usize, ty.abiSize(mod)) orelse return null;3835 const abi_size = std.math.cast(usize, ty.abiSize(mod)) orelse return null;
3836 assert(abi_size >= 1);3836 assert(abi_size >= 1);
3837 const byte_buffer = try mod.gpa.alloc(u8, abi_size);3837 const byte_buffer = try mod.gpa.alloc(u8, abi_size);
...@@ -3852,7 +3852,7 @@ pub const Value = struct {...@@ -3852,7 +3852,7 @@ pub const Value = struct {
3852 for (byte_buffer[1..]) |byte| {3852 for (byte_buffer[1..]) |byte| {
3853 if (byte != first_byte) return null;3853 if (byte != first_byte) return null;
3854 }3854 }
3855 return try mod.intValue(Type.u8, first_byte);3855 return first_byte;
3856 }3856 }
38573857
3858 pub fn isGenericPoison(val: Value) bool {3858 pub fn isGenericPoison(val: Value) bool {
src/zig_llvm.cpp-16
...@@ -408,22 +408,6 @@ void ZigLLVMSetTailCallKind(LLVMValueRef Call, enum ZigLLVMTailCallKind TailCall...@@ -408,22 +408,6 @@ void ZigLLVMSetTailCallKind(LLVMValueRef Call, enum ZigLLVMTailCallKind TailCall
408 unwrap<CallInst>(Call)->setTailCallKind(TCK);408 unwrap<CallInst>(Call)->setTailCallKind(TCK);
409}409}
410410
411LLVMValueRef ZigLLVMBuildMemCpy(LLVMBuilderRef B, LLVMValueRef Dst, unsigned DstAlign,
412 LLVMValueRef Src, unsigned SrcAlign, LLVMValueRef Size, bool isVolatile)
413{
414 CallInst *call_inst = unwrap(B)->CreateMemCpy(unwrap(Dst),
415 MaybeAlign(DstAlign), unwrap(Src), MaybeAlign(SrcAlign), unwrap(Size), isVolatile);
416 return wrap(call_inst);
417}
418
419LLVMValueRef ZigLLVMBuildMemSet(LLVMBuilderRef B, LLVMValueRef Ptr, LLVMValueRef Val, LLVMValueRef Size,
420 unsigned Align, bool isVolatile)
421{
422 CallInst *call_inst = unwrap(B)->CreateMemSet(unwrap(Ptr), unwrap(Val), unwrap(Size),
423 MaybeAlign(Align), isVolatile);
424 return wrap(call_inst);
425}
426
427void ZigLLVMFnSetSubprogram(LLVMValueRef fn, ZigLLVMDISubprogram *subprogram) {411void ZigLLVMFnSetSubprogram(LLVMValueRef fn, ZigLLVMDISubprogram *subprogram) {
428 assert( isa<Function>(unwrap(fn)) );412 assert( isa<Function>(unwrap(fn)) );
429 Function *unwrapped_function = reinterpret_cast<Function*>(unwrap(fn));413 Function *unwrapped_function = reinterpret_cast<Function*>(unwrap(fn));
src/zig_llvm.h-6
...@@ -122,12 +122,6 @@ enum ZigLLVM_CallingConv {...@@ -122,12 +122,6 @@ enum ZigLLVM_CallingConv {
122 ZigLLVM_MaxID = 1023,122 ZigLLVM_MaxID = 1023,
123};123};
124124
125ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildMemCpy(LLVMBuilderRef B, LLVMValueRef Dst, unsigned DstAlign,
126 LLVMValueRef Src, unsigned SrcAlign, LLVMValueRef Size, bool isVolatile);
127
128ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildMemSet(LLVMBuilderRef B, LLVMValueRef Ptr, LLVMValueRef Val, LLVMValueRef Size,
129 unsigned Align, bool isVolatile);
130
131ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildNSWShl(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,125ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildNSWShl(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,
132 const char *name);126 const char *name);
133ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildNUWShl(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,127ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildNUWShl(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,