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 {...@@ -2430,6 +2430,11 @@ pub const Function = struct {
2430 @"llvm.sqrt.",2430 @"llvm.sqrt.",
2431 @"llvm.trunc.",2431 @"llvm.trunc.",
2432 @"llvm.fma.",2432 @"llvm.fma.",
2433 @"llvm.bitreverse.",
2434 @"llvm.bswap.",
2435 @"llvm.ctpop.",
2436 @"llvm.ctlz.",
2437 @"llvm.cttz.",
2433 @"llvm.sadd.sat.",2438 @"llvm.sadd.sat.",
2434 @"llvm.smax.",2439 @"llvm.smax.",
2435 @"llvm.smin.",2440 @"llvm.smin.",
...@@ -2572,6 +2577,8 @@ pub const Function = struct {...@@ -2572,6 +2577,8 @@ pub const Function = struct {
2572 .@"fsub fast",2577 .@"fsub fast",
2573 .@"llvm.maxnum.",2578 .@"llvm.maxnum.",
2574 .@"llvm.minnum.",2579 .@"llvm.minnum.",
2580 .@"llvm.ctlz.",
2581 .@"llvm.cttz.",
2575 .@"llvm.sadd.sat.",2582 .@"llvm.sadd.sat.",
2576 .@"llvm.smax.",2583 .@"llvm.smax.",
2577 .@"llvm.smin.",2584 .@"llvm.smin.",
...@@ -2716,6 +2723,9 @@ pub const Function = struct {...@@ -2716,6 +2723,9 @@ pub const Function = struct {
2716 .@"llvm.sin.",2723 .@"llvm.sin.",
2717 .@"llvm.sqrt.",2724 .@"llvm.sqrt.",
2718 .@"llvm.trunc.",2725 .@"llvm.trunc.",
2726 .@"llvm.bitreverse.",
2727 .@"llvm.bswap.",
2728 .@"llvm.ctpop.",
2719 => @as(Value, @enumFromInt(instruction.data)).typeOfWip(wip),2729 => @as(Value, @enumFromInt(instruction.data)).typeOfWip(wip),
2720 .getelementptr,2730 .getelementptr,
2721 .@"getelementptr inbounds",2731 .@"getelementptr inbounds",
...@@ -2783,6 +2793,8 @@ pub const Function = struct {...@@ -2783,6 +2793,8 @@ pub const Function = struct {
2783 .@"fsub fast",2793 .@"fsub fast",
2784 .@"llvm.maxnum.",2794 .@"llvm.maxnum.",
2785 .@"llvm.minnum.",2795 .@"llvm.minnum.",
2796 .@"llvm.ctlz.",
2797 .@"llvm.cttz.",
2786 .@"llvm.sadd.sat.",2798 .@"llvm.sadd.sat.",
2787 .@"llvm.smax.",2799 .@"llvm.smax.",
2788 .@"llvm.smin.",2800 .@"llvm.smin.",
...@@ -2928,6 +2940,9 @@ pub const Function = struct {...@@ -2928,6 +2940,9 @@ pub const Function = struct {
2928 .@"llvm.sin.",2940 .@"llvm.sin.",
2929 .@"llvm.sqrt.",2941 .@"llvm.sqrt.",
2930 .@"llvm.trunc.",2942 .@"llvm.trunc.",
2943 .@"llvm.bitreverse.",
2944 .@"llvm.bswap.",
2945 .@"llvm.ctpop.",
2931 => @as(Value, @enumFromInt(instruction.data)).typeOf(function_index, builder),2946 => @as(Value, @enumFromInt(instruction.data)).typeOf(function_index, builder),
2932 .getelementptr,2947 .getelementptr,
2933 .@"getelementptr inbounds",2948 .@"getelementptr inbounds",
...@@ -3486,6 +3501,10 @@ pub const WipFunction = struct {...@@ -3486,6 +3501,10 @@ pub const WipFunction = struct {
3486 .@"llvm.sqrt.",3501 .@"llvm.sqrt.",
3487 .@"llvm.trunc.",3502 .@"llvm.trunc.",
3488 => assert(val.typeOfWip(self).scalarType(self.builder).isFloatingPoint()),3503 => 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)),
3489 else => unreachable,3508 else => unreachable,
3490 }3509 }
3491 try self.ensureUnusedExtraCapacity(1, NoExtra, 0);3510 try self.ensureUnusedExtraCapacity(1, NoExtra, 0);
...@@ -3507,6 +3526,9 @@ pub const WipFunction = struct {...@@ -3507,6 +3526,9 @@ pub const WipFunction = struct {
3507 .@"llvm.sin.",3526 .@"llvm.sin.",
3508 .@"llvm.sqrt.",3527 .@"llvm.sqrt.",
3509 .@"llvm.trunc.",3528 .@"llvm.trunc.",
3529 .@"llvm.bitreverse.",
3530 .@"llvm.bswap.",
3531 .@"llvm.ctpop.",
3510 => {},3532 => {},
3511 else => unreachable,3533 else => unreachable,
3512 }3534 }
...@@ -3525,6 +3547,9 @@ pub const WipFunction = struct {...@@ -3525,6 +3547,9 @@ pub const WipFunction = struct {
3525 .@"llvm.sin." => &llvm.Builder.buildSin,3547 .@"llvm.sin." => &llvm.Builder.buildSin,
3526 .@"llvm.sqrt." => &llvm.Builder.buildSqrt,3548 .@"llvm.sqrt." => &llvm.Builder.buildSqrt,
3527 .@"llvm.trunc." => &llvm.Builder.buildFTrunc,3549 .@"llvm.trunc." => &llvm.Builder.buildFTrunc,
3550 .@"llvm.bitreverse." => &llvm.Builder.buildBitReverse,
3551 .@"llvm.bswap." => &llvm.Builder.buildBSwap,
3552 .@"llvm.ctpop." => &llvm.Builder.buildCTPop,
3528 else => unreachable,3553 else => unreachable,
3529 }(self.llvm.builder, val.toLlvm(self), instruction.llvmName(self)));3554 }(self.llvm.builder, val.toLlvm(self), instruction.llvmName(self)));
3530 }3555 }
...@@ -3602,6 +3627,9 @@ pub const WipFunction = struct {...@@ -3602,6 +3627,9 @@ pub const WipFunction = struct {
3602 .urem,3627 .urem,
3603 .xor,3628 .xor,
3604 => assert(lhs.typeOfWip(self) == rhs.typeOfWip(self)),3629 => 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),
3605 else => unreachable,3633 else => unreachable,
3606 }3634 }
3607 try self.ensureUnusedExtraCapacity(1, Instruction.Binary, 0);3635 try self.ensureUnusedExtraCapacity(1, Instruction.Binary, 0);
...@@ -3639,6 +3667,8 @@ pub const WipFunction = struct {...@@ -3639,6 +3667,8 @@ pub const WipFunction = struct {
3639 .fsub, .@"fsub fast" => &llvm.Builder.buildFSub,3667 .fsub, .@"fsub fast" => &llvm.Builder.buildFSub,
3640 .@"llvm.maxnum." => &llvm.Builder.buildMaxNum,3668 .@"llvm.maxnum." => &llvm.Builder.buildMaxNum,
3641 .@"llvm.minnum." => &llvm.Builder.buildMinNum,3669 .@"llvm.minnum." => &llvm.Builder.buildMinNum,
3670 .@"llvm.ctlz." => &llvm.Builder.buildCTLZ,
3671 .@"llvm.cttz." => &llvm.Builder.buildCTTZ,
3642 .@"llvm.sadd.sat." => &llvm.Builder.buildSAddSat,3672 .@"llvm.sadd.sat." => &llvm.Builder.buildSAddSat,
3643 .@"llvm.smax." => &llvm.Builder.buildSMax,3673 .@"llvm.smax." => &llvm.Builder.buildSMax,
3644 .@"llvm.smin." => &llvm.Builder.buildSMin,3674 .@"llvm.smin." => &llvm.Builder.buildSMin,
...@@ -4669,6 +4699,8 @@ pub const WipFunction = struct {...@@ -4669,6 +4699,8 @@ pub const WipFunction = struct {
4669 .@"icmp ult",4699 .@"icmp ult",
4670 .@"llvm.maxnum.",4700 .@"llvm.maxnum.",
4671 .@"llvm.minnum.",4701 .@"llvm.minnum.",
4702 .@"llvm.ctlz.",
4703 .@"llvm.cttz.",
4672 .@"llvm.sadd.sat.",4704 .@"llvm.sadd.sat.",
4673 .@"llvm.smax.",4705 .@"llvm.smax.",
4674 .@"llvm.smin.",4706 .@"llvm.smin.",
...@@ -4809,6 +4841,9 @@ pub const WipFunction = struct {...@@ -4809,6 +4841,9 @@ pub const WipFunction = struct {
4809 .@"llvm.sin.",4841 .@"llvm.sin.",
4810 .@"llvm.sqrt.",4842 .@"llvm.sqrt.",
4811 .@"llvm.trunc.",4843 .@"llvm.trunc.",
4844 .@"llvm.bitreverse.",
4845 .@"llvm.bswap.",
4846 .@"llvm.ctpop.",
4812 => instruction.data = @intFromEnum(instructions.map(@enumFromInt(instruction.data))),4847 => instruction.data = @intFromEnum(instructions.map(@enumFromInt(instruction.data))),
4813 .getelementptr,4848 .getelementptr,
4814 .@"getelementptr inbounds",4849 .@"getelementptr inbounds",
...@@ -7706,6 +7741,9 @@ pub fn printUnbuffered(...@@ -7706,6 +7741,9 @@ pub fn printUnbuffered(
7706 .@"llvm.sin.",7741 .@"llvm.sin.",
7707 .@"llvm.sqrt.",7742 .@"llvm.sqrt.",
7708 .@"llvm.trunc.",7743 .@"llvm.trunc.",
7744 .@"llvm.bitreverse.",
7745 .@"llvm.bswap.",
7746 .@"llvm.ctpop.",
7709 => |tag| {7747 => |tag| {
7710 const val: Value = @enumFromInt(instruction.data);7748 const val: Value = @enumFromInt(instruction.data);
7711 try writer.print(" {s} {%}\n", .{7749 try writer.print(" {s} {%}\n", .{
...@@ -7762,6 +7800,8 @@ pub fn printUnbuffered(...@@ -7762,6 +7800,8 @@ pub fn printUnbuffered(
7762 },7800 },
7763 .@"llvm.maxnum.",7801 .@"llvm.maxnum.",
7764 .@"llvm.minnum.",7802 .@"llvm.minnum.",
7803 .@"llvm.ctlz.",
7804 .@"llvm.cttz.",
7765 .@"llvm.sadd.sat.",7805 .@"llvm.sadd.sat.",
7766 .@"llvm.smax.",7806 .@"llvm.smax.",
7767 .@"llvm.smin.",7807 .@"llvm.smin.",
src/codegen/llvm/bindings.zig+15
...@@ -1065,6 +1065,21 @@ pub const Builder = opaque {...@@ -1065,6 +1065,21 @@ pub const Builder = opaque {
1065 pub const buildFTrunc = ZigLLVMBuildFTrunc;1065 pub const buildFTrunc = ZigLLVMBuildFTrunc;
1066 extern fn ZigLLVMBuildFTrunc(builder: *Builder, V: *Value, name: [*:0]const u8) *Value;1066 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
1068 pub const buildFMA = ZigLLVMBuildFMA;1083 pub const buildFMA = ZigLLVMBuildFMA;
1069 extern fn ZigLLVMBuildFMA(builder: *Builder, a: *Value, b: *Value, c: *Value, name: [*:0]const u8) *Value;1084 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...@@ -546,6 +546,31 @@ LLVMValueRef ZigLLVMBuildFTrunc(LLVMBuilderRef B, LLVMValueRef V, const char *na
546 return wrap(call_inst);546 return wrap(call_inst);
547}547}
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
549LLVMValueRef ZigLLVMBuildFMA(LLVMBuilderRef builder, LLVMValueRef A, LLVMValueRef B, LLVMValueRef C, const char *name) {574LLVMValueRef ZigLLVMBuildFMA(LLVMBuilderRef builder, LLVMValueRef A, LLVMValueRef B, LLVMValueRef C, const char *name) {
550 llvm::Type* types[1] = {575 llvm::Type* types[1] = {
551 unwrap(A)->getType(),576 unwrap(A)->getType(),
src/zig_llvm.h+7
...@@ -155,6 +155,13 @@ ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSin(LLVMBuilderRef builder, LLVMValueRef V...@@ -155,6 +155,13 @@ ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSin(LLVMBuilderRef builder, LLVMValueRef V
155ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSqrt(LLVMBuilderRef builder, LLVMValueRef V, const char* name);155ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildSqrt(LLVMBuilderRef builder, LLVMValueRef V, const char* name);
156ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildFTrunc(LLVMBuilderRef builder, LLVMValueRef V, const char* name);156ZIG_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
158ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildFMA(LLVMBuilderRef builder, LLVMValueRef A, LLVMValueRef B, LLVMValueRef C, const char* name);165ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildFMA(LLVMBuilderRef builder, LLVMValueRef A, LLVMValueRef B, LLVMValueRef C, const char* name);
159166
160ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildMaxNum(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);167ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildMaxNum(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char* name);