authorgravatar for liljaanton2001@gmail.comantlilja <liljaanton2001@gmail.com> 2023-08-06 00:58:10+02:00
committergravatar for liljaanton2001@gmail.comantlilja <liljaanton2001@gmail.com> 2023-08-06 01:46:57+02:00
log86f61a9d2641300a733eee2edc10f57bb3243c57
tree8aeaa5fa87b8722e701a7093665c11c43ea7cb62
parent2b4ac7c6b3563905178b791f2e15631a9a38f7ff
signaturelock-open Commit is signed but in an unrecognized format.

Implement bitop intrinsics in new LLVM IR builder

* llvm.bitreverse * llvm.bswap * llvm.ctpop * llvm.ctlz * llvm.cttz

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

src/codegen/llvm/Builder.zig+40
......@@ -2430,6 +2430,11 @@ pub const Function = struct {
24302430 @"llvm.sqrt.",
24312431 @"llvm.trunc.",
24322432 @"llvm.fma.",
2433 @"llvm.bitreverse.",
2434 @"llvm.bswap.",
2435 @"llvm.ctpop.",
2436 @"llvm.ctlz.",
2437 @"llvm.cttz.",
24332438 @"llvm.sadd.sat.",
24342439 @"llvm.smax.",
24352440 @"llvm.smin.",
......@@ -2572,6 +2577,8 @@ pub const Function = struct {
25722577 .@"fsub fast",
25732578 .@"llvm.maxnum.",
25742579 .@"llvm.minnum.",
2580 .@"llvm.ctlz.",
2581 .@"llvm.cttz.",
25752582 .@"llvm.sadd.sat.",
25762583 .@"llvm.smax.",
25772584 .@"llvm.smin.",
......@@ -2716,6 +2723,9 @@ pub const Function = struct {
27162723 .@"llvm.sin.",
27172724 .@"llvm.sqrt.",
27182725 .@"llvm.trunc.",
2726 .@"llvm.bitreverse.",
2727 .@"llvm.bswap.",
2728 .@"llvm.ctpop.",
27192729 => @as(Value, @enumFromInt(instruction.data)).typeOfWip(wip),
27202730 .getelementptr,
27212731 .@"getelementptr inbounds",
......@@ -2783,6 +2793,8 @@ pub const Function = struct {
27832793 .@"fsub fast",
27842794 .@"llvm.maxnum.",
27852795 .@"llvm.minnum.",
2796 .@"llvm.ctlz.",
2797 .@"llvm.cttz.",
27862798 .@"llvm.sadd.sat.",
27872799 .@"llvm.smax.",
27882800 .@"llvm.smin.",
......@@ -2928,6 +2940,9 @@ pub const Function = struct {
29282940 .@"llvm.sin.",
29292941 .@"llvm.sqrt.",
29302942 .@"llvm.trunc.",
2943 .@"llvm.bitreverse.",
2944 .@"llvm.bswap.",
2945 .@"llvm.ctpop.",
29312946 => @as(Value, @enumFromInt(instruction.data)).typeOf(function_index, builder),
29322947 .getelementptr,
29332948 .@"getelementptr inbounds",
......@@ -3486,6 +3501,10 @@ pub const WipFunction = struct {
34863501 .@"llvm.sqrt.",
34873502 .@"llvm.trunc.",
34883503 => assert(val.typeOfWip(self).scalarType(self.builder).isFloatingPoint()),
3504 .@"llvm.bitreverse.",
3505 .@"llvm.bswap.",
3506 .@"llvm.ctpop.",
3507 => assert(val.typeOfWip(self).scalarType(self.builder).isInteger(self.builder)),
34893508 else => unreachable,
34903509 }
34913510 try self.ensureUnusedExtraCapacity(1, NoExtra, 0);
......@@ -3507,6 +3526,9 @@ pub const WipFunction = struct {
35073526 .@"llvm.sin.",
35083527 .@"llvm.sqrt.",
35093528 .@"llvm.trunc.",
3529 .@"llvm.bitreverse.",
3530 .@"llvm.bswap.",
3531 .@"llvm.ctpop.",
35103532 => {},
35113533 else => unreachable,
35123534 }
......@@ -3525,6 +3547,9 @@ pub const WipFunction = struct {
35253547 .@"llvm.sin." => &llvm.Builder.buildSin,
35263548 .@"llvm.sqrt." => &llvm.Builder.buildSqrt,
35273549 .@"llvm.trunc." => &llvm.Builder.buildFTrunc,
3550 .@"llvm.bitreverse." => &llvm.Builder.buildBitReverse,
3551 .@"llvm.bswap." => &llvm.Builder.buildBSwap,
3552 .@"llvm.ctpop." => &llvm.Builder.buildCTPop,
35283553 else => unreachable,
35293554 }(self.llvm.builder, val.toLlvm(self), instruction.llvmName(self)));
35303555 }
......@@ -3602,6 +3627,9 @@ pub const WipFunction = struct {
36023627 .urem,
36033628 .xor,
36043629 => assert(lhs.typeOfWip(self) == rhs.typeOfWip(self)),
3630 .@"llvm.ctlz.",
3631 .@"llvm.cttz.",
3632 => assert(lhs.typeOfWip(self).scalarType(self.builder).isInteger(self.builder) and rhs.typeOfWip(self) == .i1),
36053633 else => unreachable,
36063634 }
36073635 try self.ensureUnusedExtraCapacity(1, Instruction.Binary, 0);
......@@ -3639,6 +3667,8 @@ pub const WipFunction = struct {
36393667 .fsub, .@"fsub fast" => &llvm.Builder.buildFSub,
36403668 .@"llvm.maxnum." => &llvm.Builder.buildMaxNum,
36413669 .@"llvm.minnum." => &llvm.Builder.buildMinNum,
3670 .@"llvm.ctlz." => &llvm.Builder.buildCTLZ,
3671 .@"llvm.cttz." => &llvm.Builder.buildCTTZ,
36423672 .@"llvm.sadd.sat." => &llvm.Builder.buildSAddSat,
36433673 .@"llvm.smax." => &llvm.Builder.buildSMax,
36443674 .@"llvm.smin." => &llvm.Builder.buildSMin,
......@@ -4669,6 +4699,8 @@ pub const WipFunction = struct {
46694699 .@"icmp ult",
46704700 .@"llvm.maxnum.",
46714701 .@"llvm.minnum.",
4702 .@"llvm.ctlz.",
4703 .@"llvm.cttz.",
46724704 .@"llvm.sadd.sat.",
46734705 .@"llvm.smax.",
46744706 .@"llvm.smin.",
......@@ -4809,6 +4841,9 @@ pub const WipFunction = struct {
48094841 .@"llvm.sin.",
48104842 .@"llvm.sqrt.",
48114843 .@"llvm.trunc.",
4844 .@"llvm.bitreverse.",
4845 .@"llvm.bswap.",
4846 .@"llvm.ctpop.",
48124847 => instruction.data = @intFromEnum(instructions.map(@enumFromInt(instruction.data))),
48134848 .getelementptr,
48144849 .@"getelementptr inbounds",
......@@ -7706,6 +7741,9 @@ pub fn printUnbuffered(
77067741 .@"llvm.sin.",
77077742 .@"llvm.sqrt.",
77087743 .@"llvm.trunc.",
7744 .@"llvm.bitreverse.",
7745 .@"llvm.bswap.",
7746 .@"llvm.ctpop.",
77097747 => |tag| {
77107748 const val: Value = @enumFromInt(instruction.data);
77117749 try writer.print(" {s} {%}\n", .{
......@@ -7762,6 +7800,8 @@ pub fn printUnbuffered(
77627800 },
77637801 .@"llvm.maxnum.",
77647802 .@"llvm.minnum.",
7803 .@"llvm.ctlz.",
7804 .@"llvm.cttz.",
77657805 .@"llvm.sadd.sat.",
77667806 .@"llvm.smax.",
77677807 .@"llvm.smin.",
src/codegen/llvm/bindings.zig+15
......@@ -1065,6 +1065,21 @@ pub const Builder = opaque {
10651065 pub const buildFTrunc = ZigLLVMBuildFTrunc;
10661066 extern fn ZigLLVMBuildFTrunc(builder: *Builder, V: *Value, name: [*:0]const u8) *Value;
10671067
1068 pub const buildBitReverse = ZigLLVMBuildBitReverse;
1069 extern fn ZigLLVMBuildBitReverse(builder: *Builder, V: *Value, name: [*:0]const u8) *Value;
1070
1071 pub const buildBSwap = ZigLLVMBuildBSwap;
1072 extern fn ZigLLVMBuildBSwap(builder: *Builder, V: *Value, name: [*:0]const u8) *Value;
1073
1074 pub const buildCTPop = ZigLLVMBuildCTPop;
1075 extern fn ZigLLVMBuildCTPop(builder: *Builder, V: *Value, name: [*:0]const u8) *Value;
1076
1077 pub const buildCTLZ = ZigLLVMBuildCTLZ;
1078 extern fn ZigLLVMBuildCTLZ(builder: *Builder, LHS: *Value, RHS: *Value, name: [*:0]const u8) *Value;
1079
1080 pub const buildCTTZ = ZigLLVMBuildCTTZ;
1081 extern fn ZigLLVMBuildCTTZ(builder: *Builder, LHS: *Value, RHS: *Value, name: [*:0]const u8) *Value;
1082
10681083 pub const buildFMA = ZigLLVMBuildFMA;
10691084 extern fn ZigLLVMBuildFMA(builder: *Builder, a: *Value, b: *Value, c: *Value, name: [*:0]const u8) *Value;
10701085
src/zig_llvm.cpp+25
......@@ -546,6 +546,31 @@ LLVMValueRef ZigLLVMBuildFTrunc(LLVMBuilderRef B, LLVMValueRef V, const char *na
546546 return wrap(call_inst);
547547}
548548
549LLVMValueRef ZigLLVMBuildBitReverse(LLVMBuilderRef B, LLVMValueRef V, const char *name) {
550 CallInst *call_inst = unwrap(B)->CreateUnaryIntrinsic(Intrinsic::bitreverse, unwrap(V), nullptr, name);
551 return wrap(call_inst);
552}
553
554LLVMValueRef ZigLLVMBuildBSwap(LLVMBuilderRef B, LLVMValueRef V, const char *name) {
555 CallInst *call_inst = unwrap(B)->CreateUnaryIntrinsic(Intrinsic::bswap, unwrap(V), nullptr, name);
556 return wrap(call_inst);
557}
558
559LLVMValueRef ZigLLVMBuildCTPop(LLVMBuilderRef B, LLVMValueRef V, const char *name) {
560 CallInst *call_inst = unwrap(B)->CreateUnaryIntrinsic(Intrinsic::ctpop, unwrap(V), nullptr, name);
561 return wrap(call_inst);
562}
563
564LLVMValueRef ZigLLVMBuildCTLZ(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name) {
565 CallInst *call_inst = unwrap(B)->CreateBinaryIntrinsic(Intrinsic::ctlz, unwrap(LHS), unwrap(RHS), nullptr, name);
566 return wrap(call_inst);
567}
568
569LLVMValueRef ZigLLVMBuildCTTZ(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, const char *name) {
570 CallInst *call_inst = unwrap(B)->CreateBinaryIntrinsic(Intrinsic::cttz, unwrap(LHS), unwrap(RHS), nullptr, name);
571 return wrap(call_inst);
572}
573
549574LLVMValueRef ZigLLVMBuildFMA(LLVMBuilderRef builder, LLVMValueRef A, LLVMValueRef B, LLVMValueRef C, const char *name) {
550575 llvm::Type* types[1] = {
551576 unwrap(A)->getType(),
src/zig_llvm.h+7
......@@ -155,6 +155,13 @@ ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSin(LLVMBuilderRef builder, LLVMValueRef V
155155ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSqrt(LLVMBuilderRef builder, LLVMValueRef V, const char* name);
156156ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildFTrunc(LLVMBuilderRef builder, LLVMValueRef V, const char* name);
157157
158ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildBitReverse(LLVMBuilderRef builder, LLVMValueRef V, const char* name);
159ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildBSwap(LLVMBuilderRef builder, LLVMValueRef V, const char* name);
160ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildCTPop(LLVMBuilderRef builder, LLVMValueRef V, const char* name);
161
162ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildCTLZ(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);
163ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildCTTZ(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);
164
158165ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildFMA(LLVMBuilderRef builder, LLVMValueRef A, LLVMValueRef B, LLVMValueRef C, const char* name);
159166
160167ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildMaxNum(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);