diff --git a/lib/std/collections/enumset.c3 b/lib/std/collections/enumset.c3 index e9eeba340..d8c27a0a6 100644 --- a/lib/std/collections/enumset.c3 +++ b/lib/std/collections/enumset.c3 @@ -8,28 +8,31 @@ module std::collections::enumset; +const IS_CHAR_ARRAY = Enum.elements > 128; + $switch + $case (Enum.elements > 128): -typedef EnumSetType @private = char[(Enum.elements + 7) / 8]; -const IS_CHAR_ARRAY = true; +def EnumSetType @private = char[(Enum.elements + 7) / 8]; + $case (Enum.elements > 64): -typedef EnumSetType @private = uint128; -const IS_CHAR_ARRAY = false; +def EnumSetType @private = uint128; + $case (Enum.elements > 32 || $$C_INT_SIZE > 32): -typedef EnumSetType @private = ulong; -const IS_CHAR_ARRAY = false; +def EnumSetType @private = ulong; + $case (Enum.elements > 16 || $$C_INT_SIZE > 16): -typedef EnumSetType @private = uint; -const IS_CHAR_ARRAY = false; +def EnumSetType @private = uint; + $case (Enum.elements > 8 || $$C_INT_SIZE > 8): -typedef EnumSetType @private = ushort; -const IS_CHAR_ARRAY = false; +def EnumSetType @private = ushort; + $default: -typedef EnumSetType @private = char; -const IS_CHAR_ARRAY = false; +def EnumSetType @private = char; + $endswitch -typedef EnumSet = distinct EnumSetType; +def EnumSet = distinct EnumSetType; fn void EnumSet.add(EnumSet* this, Enum v) { diff --git a/lib/std/math/math.c3 b/lib/std/math/math.c3 index 4644d7ba0..935b127ce 100644 --- a/lib/std/math/math.c3 +++ b/lib/std/math/math.c3 @@ -568,6 +568,13 @@ macro bool[<*>] double[<*>].comp_gt(double[<*>] x, double[<*>] y) => $$veccompgt macro bool[<*>] double[<*>].comp_ge(double[<*>] x, double[<*>] y) => $$veccompge(x, y); macro bool[<*>] double[<*>].comp_ne(double[<*>] x, double[<*>] y) => $$veccompne(x, y); +macro bool[<*>] ichar[<*>].comp_lt(ichar[<*>] x, ichar[<*>] y) => $$veccomplt(x, y); +macro bool[<*>] ichar[<*>].comp_le(ichar[<*>] x, ichar[<*>] y) => $$veccomple(x, y); +macro bool[<*>] ichar[<*>].comp_eq(ichar[<*>] x, ichar[<*>] y) => $$veccompeq(x, y); +macro bool[<*>] ichar[<*>].comp_gt(ichar[<*>] x, ichar[<*>] y) => $$veccompgt(x, y); +macro bool[<*>] ichar[<*>].comp_ge(ichar[<*>] x, ichar[<*>] y) => $$veccompge(x, y); +macro bool[<*>] ichar[<*>].comp_ne(ichar[<*>] x, ichar[<*>] y) => $$veccompne(x, y); + macro ichar ichar[<*>].sum(ichar[<*>] x) => $$reduce_add(x); macro ichar ichar[<*>].product(ichar[<*>] x) => $$reduce_mul(x); macro ichar ichar[<*>].and(ichar[<*>] x) => $$reduce_and(x); @@ -576,6 +583,13 @@ macro ichar ichar[<*>].xor(ichar[<*>] x) => $$reduce_xor(x); macro ichar ichar[<*>].max(ichar[<*>] x) => $$reduce_max(x); macro ichar ichar[<*>].min(ichar[<*>] x) => $$reduce_min(x); +macro bool[<*>] short[<*>].comp_lt(short[<*>] x, short[<*>] y) => $$veccomplt(x, y); +macro bool[<*>] short[<*>].comp_le(short[<*>] x, short[<*>] y) => $$veccomple(x, y); +macro bool[<*>] short[<*>].comp_eq(short[<*>] x, short[<*>] y) => $$veccompeq(x, y); +macro bool[<*>] short[<*>].comp_gt(short[<*>] x, short[<*>] y) => $$veccompgt(x, y); +macro bool[<*>] short[<*>].comp_ge(short[<*>] x, short[<*>] y) => $$veccompge(x, y); +macro bool[<*>] short[<*>].comp_ne(short[<*>] x, short[<*>] y) => $$veccompne(x, y); + macro short short[<*>].sum(short[<*>] x) => $$reduce_add(x); macro short short[<*>].product(short[<*>] x) => $$reduce_mul(x); macro short short[<*>].and(short[<*>] x) => $$reduce_and(x); @@ -599,6 +613,12 @@ macro int int[<*>].xor(int[<*>] x) => $$reduce_xor(x); macro int int[<*>].max(int[<*>] x) => $$reduce_max(x); macro int int[<*>].min(int[<*>] x) => $$reduce_min(x); +macro bool[<*>] long[<*>].comp_lt(long[<*>] x, long[<*>] y) => $$veccomplt(x, y); +macro bool[<*>] long[<*>].comp_le(long[<*>] x, long[<*>] y) => $$veccomple(x, y); +macro bool[<*>] long[<*>].comp_eq(long[<*>] x, long[<*>] y) => $$veccompeq(x, y); +macro bool[<*>] long[<*>].comp_gt(long[<*>] x, long[<*>] y) => $$veccompgt(x, y); +macro bool[<*>] long[<*>].comp_ge(long[<*>] x, long[<*>] y) => $$veccompge(x, y); +macro bool[<*>] long[<*>].comp_ne(long[<*>] x, long[<*>] y) => $$veccompne(x, y); macro long long[<*>].sum(long[<*>] x) => $$reduce_add(x); macro long long[<*>].product(long[<*>] x) => $$reduce_mul(x); macro long long[<*>].and(long[<*>] x) => $$reduce_and(x); @@ -607,6 +627,12 @@ macro long long[<*>].xor(long[<*>] x) => $$reduce_xor(x); macro long long[<*>].max(long[<*>] x) => $$reduce_max(x); macro long long[<*>].min(long[<*>] x) => $$reduce_min(x); +macro bool[<*>] int128[<*>].comp_lt(int128[<*>] x, int128[<*>] y) => $$veccomplt(x, y); +macro bool[<*>] int128[<*>].comp_le(int128[<*>] x, int128[<*>] y) => $$veccomple(x, y); +macro bool[<*>] int128[<*>].comp_eq(int128[<*>] x, int128[<*>] y) => $$veccompeq(x, y); +macro bool[<*>] int128[<*>].comp_gt(int128[<*>] x, int128[<*>] y) => $$veccompgt(x, y); +macro bool[<*>] int128[<*>].comp_ge(int128[<*>] x, int128[<*>] y) => $$veccompge(x, y); +macro bool[<*>] int128[<*>].comp_ne(int128[<*>] x, int128[<*>] y) => $$veccompne(x, y); macro int128 int128[<*>].sum(int128[<*>] x) => $$reduce_add(x); macro int128 int128[<*>].product(int128[<*>] x) => $$reduce_mul(x); macro int128 int128[<*>].and(int128[<*>] x) => $$reduce_and(x); @@ -630,6 +656,13 @@ macro bool bool[<*>].xor(bool[<*>] x) => $$reduce_xor(x); macro bool bool[<*>].max(bool[<*>] x) => $$reduce_max(x); macro bool bool[<*>].min(bool[<*>] x) => $$reduce_min(x); +macro bool[<*>] char[<*>].comp_lt(char[<*>] x, char[<*>] y) => $$veccomplt(x, y); +macro bool[<*>] char[<*>].comp_le(char[<*>] x, char[<*>] y) => $$veccomple(x, y); +macro bool[<*>] char[<*>].comp_eq(char[<*>] x, char[<*>] y) => $$veccompeq(x, y); +macro bool[<*>] char[<*>].comp_gt(char[<*>] x, char[<*>] y) => $$veccompgt(x, y); +macro bool[<*>] char[<*>].comp_ge(char[<*>] x, char[<*>] y) => $$veccompge(x, y); +macro bool[<*>] char[<*>].comp_ne(char[<*>] x, char[<*>] y) => $$veccompne(x, y); + macro char char[<*>].sum(char[<*>] x) => $$reduce_add(x); macro char char[<*>].product(char[<*>] x) => $$reduce_mul(x); macro char char[<*>].and(char[<*>] x) => $$reduce_and(x); @@ -638,6 +671,12 @@ macro char char[<*>].xor(char[<*>] x) => $$reduce_xor(x); macro char char[<*>].max(char[<*>] x) => $$reduce_max(x); macro char char[<*>].min(char[<*>] x) => $$reduce_min(x); +macro bool[<*>] ushort[<*>].comp_lt(ushort[<*>] x, ushort[<*>] y) => $$veccomplt(x, y); +macro bool[<*>] ushort[<*>].comp_le(ushort[<*>] x, ushort[<*>] y) => $$veccomple(x, y); +macro bool[<*>] ushort[<*>].comp_eq(ushort[<*>] x, ushort[<*>] y) => $$veccompeq(x, y); +macro bool[<*>] ushort[<*>].comp_gt(ushort[<*>] x, ushort[<*>] y) => $$veccompgt(x, y); +macro bool[<*>] ushort[<*>].comp_ge(ushort[<*>] x, ushort[<*>] y) => $$veccompge(x, y); +macro bool[<*>] ushort[<*>].comp_ne(ushort[<*>] x, ushort[<*>] y) => $$veccompne(x, y); macro ushort ushort[<*>].sum(ushort[<*>] x) => $$reduce_add(x); macro ushort ushort[<*>].product(ushort[<*>] x) => $$reduce_mul(x); @@ -647,6 +686,13 @@ macro ushort ushort[<*>].xor(ushort[<*>] x) => $$reduce_xor(x); macro ushort ushort[<*>].max(ushort[<*>] x) => $$reduce_max(x); macro ushort ushort[<*>].min(ushort[<*>] x) => $$reduce_min(x); +macro bool[<*>] uint[<*>].comp_lt(uint[<*>] x, uint[<*>] y) => $$veccomplt(x, y); +macro bool[<*>] uint[<*>].comp_le(uint[<*>] x, uint[<*>] y) => $$veccomple(x, y); +macro bool[<*>] uint[<*>].comp_eq(uint[<*>] x, uint[<*>] y) => $$veccompeq(x, y); +macro bool[<*>] uint[<*>].comp_gt(uint[<*>] x, uint[<*>] y) => $$veccompgt(x, y); +macro bool[<*>] uint[<*>].comp_ge(uint[<*>] x, uint[<*>] y) => $$veccompge(x, y); +macro bool[<*>] uint[<*>].comp_ne(uint[<*>] x, uint[<*>] y) => $$veccompne(x, y); + macro uint uint[<*>].sum(uint[<*>] x) => $$reduce_add(x); macro uint uint[<*>].product(uint[<*>] x) => $$reduce_mul(x); macro uint uint[<*>].and(uint[<*>] x) => $$reduce_and(x); @@ -655,6 +701,13 @@ macro uint uint[<*>].xor(uint[<*>] x) => $$reduce_xor(x); macro uint uint[<*>].max(uint[<*>] x) => $$reduce_max(x); macro uint uint[<*>].min(uint[<*>] x) => $$reduce_min(x); +macro bool[<*>] ulong[<*>].comp_lt(ulong[<*>] x, ulong[<*>] y) => $$veccomplt(x, y); +macro bool[<*>] ulong[<*>].comp_le(ulong[<*>] x, ulong[<*>] y) => $$veccomple(x, y); +macro bool[<*>] ulong[<*>].comp_eq(ulong[<*>] x, ulong[<*>] y) => $$veccompeq(x, y); +macro bool[<*>] ulong[<*>].comp_gt(ulong[<*>] x, ulong[<*>] y) => $$veccompgt(x, y); +macro bool[<*>] ulong[<*>].comp_ge(ulong[<*>] x, ulong[<*>] y) => $$veccompge(x, y); +macro bool[<*>] ulong[<*>].comp_ne(ulong[<*>] x, ulong[<*>] y) => $$veccompne(x, y); + macro ulong ulong[<*>].sum(ulong[<*>] x) => $$reduce_add(x); macro ulong ulong[<*>].product(ulong[<*>] x) => $$reduce_mul(x); macro ulong ulong[<*>].and(ulong[<*>] x) => $$reduce_and(x); @@ -663,6 +716,13 @@ macro ulong ulong[<*>].xor(ulong[<*>] x) => $$reduce_xor(x); macro ulong ulong[<*>].max(ulong[<*>] x) => $$reduce_max(x); macro ulong ulong[<*>].min(ulong[<*>] x) => $$reduce_min(x); +macro bool[<*>] uint128[<*>].comp_lt(uint128[<*>] x, uint128[<*>] y) => $$veccomplt(x, y); +macro bool[<*>] uint128[<*>].comp_le(uint128[<*>] x, uint128[<*>] y) => $$veccomple(x, y); +macro bool[<*>] uint128[<*>].comp_eq(uint128[<*>] x, uint128[<*>] y) => $$veccompeq(x, y); +macro bool[<*>] uint128[<*>].comp_gt(uint128[<*>] x, uint128[<*>] y) => $$veccompgt(x, y); +macro bool[<*>] uint128[<*>].comp_ge(uint128[<*>] x, uint128[<*>] y) => $$veccompge(x, y); +macro bool[<*>] uint128[<*>].comp_ne(uint128[<*>] x, uint128[<*>] y) => $$veccompne(x, y); + macro uint128 uint128[<*>].sum(uint128[<*>] x) => $$reduce_add(x); macro uint128 uint128[<*>].product(uint128[<*>] x) => $$reduce_mul(x); macro uint128 uint128[<*>].and(uint128[<*>] x) => $$reduce_and(x); diff --git a/src/compiler/llvm_codegen.c b/src/compiler/llvm_codegen.c index 816c7b8ef..0ee98a554 100644 --- a/src/compiler/llvm_codegen.c +++ b/src/compiler/llvm_codegen.c @@ -194,7 +194,7 @@ LLVMValueRef llvm_emit_const_initializer(GenContext *c, ConstInitializer *const_ vec_add(parts, llvm_emit_const_array_padding(element_type_llvm, diff, &was_modified)); } LLVMValueRef value = llvm_emit_const_initializer(c, element->init_array_value.element); - if (LLVMTypeOf(value) == element_type_llvm) was_modified = true; + if (LLVMTypeOf(value) != element_type_llvm) was_modified = true; vec_add(parts, value); current_index = element_index + 1; } @@ -208,6 +208,10 @@ LLVMValueRef llvm_emit_const_initializer(GenContext *c, ConstInitializer *const_ { return llvm_get_unnamed_struct(c, parts, pack); } + if (type_flat_is_vector(array_type)) + { + return LLVMConstVector(parts, vec_size(parts)); + } return llvm_get_array(element_type_llvm, parts, vec_size(parts)); } case CONST_INIT_UNION: diff --git a/src/version.h b/src/version.h index 3689aa497..fd5133a13 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define COMPILER_VERSION "0.4.503" \ No newline at end of file +#define COMPILER_VERSION "0.4.504" \ No newline at end of file diff --git a/test/test_suite/clang/2002-03.c3t b/test/test_suite/clang/2002-03.c3t index 93b782698..e0a4166c1 100644 --- a/test/test_suite/clang/2002-03.c3t +++ b/test/test_suite/clang/2002-03.c3t @@ -58,7 +58,7 @@ fn char* foo() { @test.arr = local_unnamed_addr global { ptr, ptr, [3 x ptr] } zeroinitializer, align 16 @test.f = local_unnamed_addr global { float, float, [10 x float] } { float 0x3FF3AE1480000000, float 0x40415999A0000000, [10 x float] zeroinitializer }, align 16 @test.array = local_unnamed_addr global { %Test, %Test, [8 x %Test] } { %Test { i32 2, double 1.200000e+01 }, %Test { i32 3, double 2.400000e+01 }, [8 x %Test] zeroinitializer }, align 16 -@test.b = local_unnamed_addr global { [4 x i32], { i32, i32, i32, i32 }, { i32, i32, [2 x i32] }, [4 x i32] } { [4 x i32] [i32 1, i32 2, i32 3, i32 4], { i32, i32, i32, i32 } { i32 5, i32 6, i32 7, i32 0 }, { i32, i32, [2 x i32] } { i32 8, i32 9, [2 x i32] zeroinitializer }, [4 x i32] zeroinitializer }, align 16 +@test.b = local_unnamed_addr global { [4 x i32], [4 x i32], { i32, i32, [2 x i32] }, [4 x i32] } { [4 x i32] [i32 1, i32 2, i32 3, i32 4], [4 x i32] [i32 5, i32 6, i32 7, i32 0], { i32, i32, [2 x i32] } { i32 8, i32 9, [2 x i32] zeroinitializer }, [4 x i32] zeroinitializer }, align 16 @test.link = local_unnamed_addr global [3 x %Connection] [%Connection { i64 1, [10 x i8] c"link1\00\00\00\00\00", i64 10 }, %Connection { i64 2, [10 x i8] c"link2\00\00\00\00\00", i64 20 }, %Connection { i64 3, [10 x i8] c"link3\00\00\00\00\00", i64 30 }], align 16 @.str = private unnamed_addr constant [4 x i8] c"\1F\C2\8B\00", align 1 @.str.7 = private unnamed_addr constant [32 x i8] c"*** Word \22%s\22 on line %d is not\00", align 1 @@ -81,14 +81,12 @@ entry: store i32 0, ptr %lLS, align 4 %intbool = icmp ne i32 %1, 0 br i1 %intbool, label %if.then, label %if.exit - if.then: ; preds = %entry %2 = load i32, ptr %lLS, align 4 %3 = load i32, ptr %asa, align 4 %add = add i32 %2, %3 store i32 %add, ptr %asa, align 4 br label %if.exit - if.exit: ; preds = %if.then, %entry %4 = load i32, ptr %asa, align 4 %5 = load double, ptr %val, align 8 diff --git a/test/test_suite/vector/vector_consts.c3t b/test/test_suite/vector/vector_consts.c3t new file mode 100644 index 000000000..ac8d5e1c7 --- /dev/null +++ b/test/test_suite/vector/vector_consts.c3t @@ -0,0 +1,46 @@ +// #target: macos-x64 +module foo; +import std::math; +fn int x(char[<8>] a, char[<8>] b) +{ + bool[<8>] z = a.comp_eq(b); + return (char[<8>] { [0..7] = 255 } & (char[<8>])z + ~(char[<8>])z & char[<8>] { 0, 1, 2, 3, 4, 5, 6, 7 }).min(); +} + +/* #expect: foo.ll + +define i32 @foo.x(double %0, double %1) #0 { +entry: + %a = alloca <8 x i8>, align 8 + %b = alloca <8 x i8>, align 8 + %z = alloca <8 x i8>, align 8 + %x = alloca <8 x i8>, align 1 + %y = alloca <8 x i8>, align 1 + %x1 = alloca <8 x i8>, align 1 + store double %0, ptr %a, align 8 + store double %1, ptr %b, align 8 + %2 = load <8 x i8>, ptr %a, align 8 + store <8 x i8> %2, ptr %x, align 1 + %3 = load <8 x i8>, ptr %b, align 8 + store <8 x i8> %3, ptr %y, align 1 + %4 = load <8 x i8>, ptr %x, align 1 + %5 = load <8 x i8>, ptr %y, align 1 + %eq = icmp eq <8 x i8> %4, %5 + %6 = sext <8 x i1> %eq to <8 x i8> + store <8 x i8> %6, ptr %z, align 8 + %7 = load <8 x i8>, ptr %z, align 8 + %8 = trunc <8 x i8> %7 to <8 x i1> + %9 = sext <8 x i1> %8 to <8 x i8> + %and = and <8 x i8> , %9 + %10 = load <8 x i8>, ptr %z, align 8 + %11 = trunc <8 x i8> %10 to <8 x i1> + %12 = sext <8 x i1> %11 to <8 x i8> + %bnot = xor <8 x i8> %12, + %and2 = and <8 x i8> %bnot, + %add = add <8 x i8> %and, %and2 + store <8 x i8> %add, ptr %x1, align 1 + %13 = load <8 x i8>, ptr %x1, align 1 + %14 = call i8 @llvm.vector.reduce.umin.v8i8(<8 x i8> %13) + %zext = zext i8 %14 to i32 + ret i32 %zext +}