Commit 2485f30046
Changed files (2)
src
test
stage1
behavior
src/ir.cpp
@@ -20363,24 +20363,45 @@ static IrInstGen *ir_analyze_bin_not(IrAnalyze *ira, IrInstSrcUnOp *instruction)
if (type_is_invalid(expr_type))
return ira->codegen->invalid_inst_gen;
- if (expr_type->id == ZigTypeIdInt) {
- if (instr_is_comptime(value)) {
- ZigValue *target_const_val = ir_resolve_const(ira, value, UndefBad);
- if (target_const_val == nullptr)
- return ira->codegen->invalid_inst_gen;
+ ZigType *scalar_type = (expr_type->id == ZigTypeIdVector) ?
+ expr_type->data.vector.elem_type : expr_type;
- IrInstGen *result = ir_const(ira, &instruction->base.base, expr_type);
- bigint_not(&result->value->data.x_bigint, &target_const_val->data.x_bigint,
- expr_type->data.integral.bit_count, expr_type->data.integral.is_signed);
- return result;
+ if (scalar_type->id != ZigTypeIdInt) {
+ ir_add_error(ira, &instruction->base.base,
+ buf_sprintf("unable to perform binary not operation on type '%s'", buf_ptr(&expr_type->name)));
+ return ira->codegen->invalid_inst_gen;
+ }
+
+ if (instr_is_comptime(value)) {
+ ZigValue *expr_val = ir_resolve_const(ira, value, UndefBad);
+ if (expr_val == nullptr)
+ return ira->codegen->invalid_inst_gen;
+
+ IrInstGen *result = ir_const(ira, &instruction->base.base, expr_type);
+
+ if (expr_type->id == ZigTypeIdVector) {
+ expand_undef_array(ira->codegen, expr_val);
+ result->value->special = ConstValSpecialUndef;
+ expand_undef_array(ira->codegen, result->value);
+
+ for (size_t i = 0; i < expr_type->data.vector.len; i++) {
+ ZigValue *src_val = &expr_val->data.x_array.data.s_none.elements[i];
+ ZigValue *dst_val = &result->value->data.x_array.data.s_none.elements[i];
+
+ dst_val->type = scalar_type;
+ dst_val->special = ConstValSpecialStatic;
+ bigint_not(&dst_val->data.x_bigint, &src_val->data.x_bigint,
+ scalar_type->data.integral.bit_count, scalar_type->data.integral.is_signed);
+ }
+ } else {
+ bigint_not(&result->value->data.x_bigint, &expr_val->data.x_bigint,
+ scalar_type->data.integral.bit_count, scalar_type->data.integral.is_signed);
}
- return ir_build_binary_not(ira, &instruction->base.base, value, expr_type);
+ return result;
}
- ir_add_error(ira, &instruction->base.base,
- buf_sprintf("unable to perform binary not operation on type '%s'", buf_ptr(&expr_type->name)));
- return ira->codegen->invalid_inst_gen;
+ return ir_build_binary_not(ira, &instruction->base.base, value, expr_type);
}
static IrInstGen *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstSrcUnOp *instruction) {
test/stage1/behavior/vector.zig
@@ -351,3 +351,28 @@ test "vector division operators" {
S.doTheTest();
comptime S.doTheTest();
}
+
+test "vector bitwise not operator" {
+ const S = struct {
+ fn doTheTestNot(comptime T: type, x: @Vector(4, T)) void {
+ var y = ~x;
+ for (@as([4]T, y)) |v, i| {
+ expectEqual(~x[i], v);
+ }
+ }
+ fn doTheTest() void {
+ doTheTestNot(u8, [_]u8{ 0, 2, 4, 255 });
+ doTheTestNot(u16, [_]u16{ 0, 2, 4, 255 });
+ doTheTestNot(u32, [_]u32{ 0, 2, 4, 255 });
+ doTheTestNot(u64, [_]u64{ 0, 2, 4, 255 });
+
+ doTheTestNot(u8, [_]u8{ 0, 2, 4, 255 });
+ doTheTestNot(u16, [_]u16{ 0, 2, 4, 255 });
+ doTheTestNot(u32, [_]u32{ 0, 2, 4, 255 });
+ doTheTestNot(u64, [_]u64{ 0, 2, 4, 255 });
+ }
+ };
+
+ S.doTheTest();
+ comptime S.doTheTest();
+}