Skip to content

Commit

Permalink
Some minor swizzle updates and updated release notes and tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
lerno committed Feb 26, 2024
1 parent e126ad7 commit 0ad1b76
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 70 deletions.
1 change: 1 addition & 0 deletions releasenotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- Private / local globals now have `internal` visibility in LLVM.
- Updated enum syntax.
- `inline` on function parameters for implicit conversions.
- 'rgba' also available for swizzling.

### Fixes

Expand Down
2 changes: 2 additions & 0 deletions src/compiler/compiler_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -3585,3 +3585,5 @@ INLINE const char *section_from_id(SectionId id)
{
return id ? global_context.section_list[id - 1] + SECTION_PREFIX_LEN : NULL;
}

extern char swizzle[256];
23 changes: 1 addition & 22 deletions src/compiler/llvm_codegen_expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -6851,28 +6851,7 @@ static void llvm_emit_swizzle(GenContext *c, BEValue *value, Expr *expr)
const char *sw_ptr = expr->swizzle_expr.swizzle;
for (unsigned i = 0; i < vec_len; i++)
{
int index;
switch (sw_ptr[i])
{
case 'x':
case 'r':
index = 0;
break;
case 'y':
case 'g':
index = 1;
break;
case 'z':
case 'b':
index = 2;
break;
case 'w':
case 'a':
index = 3;
break;
default:
UNREACHABLE
}
int index = (swizzle[(int)sw_ptr[i]] - 1) & 0xF;
mask_val[i] = llvm_const_int(c, type_uint, index);
}
LLVMValueRef res = LLVMBuildShuffleVector(c->builder, parent, LLVMGetUndef(LLVMTypeOf(parent)), LLVMConstVector(mask_val, vec_len), sw_ptr);
Expand Down
59 changes: 12 additions & 47 deletions src/compiler/sema_expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -3934,59 +3934,25 @@ static inline bool sema_expr_analyse_swizzle(SemaContext *context, Expr *expr, E
unsigned vec_len = flat_type->array.len;
Type *indexed_type = type_get_indexed_type(parent->type);
assert(len > 0);
bool in_xyzw = false;
bool in_rgba = false;
int index;
for (unsigned i = 0; i < len; i++)
{
switch (kw[i])
char val = swizzle[(int)kw[i]] - 1;
if ((val & 0xF) >= vec_len)
{
case 'x':
in_xyzw = true;
index = 0;
break;
case 'r':
in_rgba = true;
index = 0;
break;
case 'y':
in_xyzw = true;
index = 1;
break;
case 'g':
in_rgba = true;
index = 1;
break;
case 'z':
in_xyzw = true;
index = 2;
break;
case 'b':
in_rgba = true;
index = 2;
break;
case 'w':
in_xyzw = true;
index = 3;
break;
case 'a':
in_rgba = true;
index = 3;
break;
default:
SEMA_ERROR(expr, "The '%c' component is not suported in a vector of length %d.", kw[i], vec_len);
return false;
RETURN_SEMA_ERROR(expr, "The '%c' component is not present in a vector of length %d, did you assume a longer vector?", kw[i], vec_len);
return false;
}
if (index >= vec_len)
if (i == 0)
{
SEMA_ERROR(expr, "The '%c' component is not present in a vector of length %d.", kw[i], vec_len);
return false;
index = val;
}
if ((index ^ val) & 0x10)
{
RETURN_SEMA_ERROR(expr, "Mixing [xyzw] and [rgba] is not permitted, you will need to select one of them.");
}
}
if (in_xyzw && in_rgba)
{
RETURN_SEMA_ERROR(expr, "Simultaneous usage of [xyzw] and [rgba] is disallowed.");
}
index &= 0xF;
if (len == 1)
{
expr->expr_kind = EXPR_SUBSCRIPT_ADDR;
Expand Down Expand Up @@ -4200,8 +4166,7 @@ static inline bool sema_expr_analyse_access(SemaContext *context, Expr *expr, bo
{
for (unsigned i = 0; i < len; i++)
{
char c = kw[i];
if (!strchr("xyzwrgba", c)) goto NOT_SWIZZLE;
if (!swizzle[(int)kw[i]]) goto NOT_SWIZZLE;
}
// TODO should we do a missing for this as well?
return sema_expr_analyse_swizzle(context, expr, parent, flat_type, kw, len);
Expand Down
3 changes: 3 additions & 0 deletions src/compiler/semantic_analyser.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
#include <compiler_tests/benchmark.h>
#include "sema_internal.h"

char swizzle[256] = { ['x'] = 0x01, ['y'] = 0x02, ['z'] = 0x03, ['w'] = 0x04,
['r'] = 0x11, ['g'] = 0x12, ['b'] = 0x13, ['a'] = 0x14 };

void context_change_scope_with_flags(SemaContext *context, ScopeFlags flags)
{
unsigned depth = context->active_scope.depth + 1;
Expand Down
11 changes: 11 additions & 0 deletions test/test_suite/vector/swizzling.c3
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// #target: macos-x64

fn void! swizzle_test()
{
int[<4>] abc = { 1, 2, 3, 4 };
int[<3>] z = abc.rbx; // #error: Mixing
int[<2>] gh;
int[<2>] uh = gh.xz; // #error: component is not present

}

11 changes: 10 additions & 1 deletion test/unit/regression/swizzle.c3
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,13 @@ fn void test_swizzle()
int[<4>] b = { 100, 1000, 10000, 100000 };
assert($$swizzle(a, 0, 1, 1, 3) == int[<4>] { 1, 2, 2, 4 });
assert($$swizzle2(a, b, 0, 1, 4, 6, 2) == int[<5>] { 1, 2, 100, 10000, 3 });
}
}

fn void! swizzle_builtin()
{
int[<4>] abc = { 1, 2, 3, 4 };
assert(abc.rb == { 1, 3 });
assert(abc.xxww == { 1, 1, 4, 4 });
abc = abc.abgr;
assert(abc == { 4, 3, 2, 1 });
}

0 comments on commit 0ad1b76

Please sign in to comment.