@@ -753,6 +753,29 @@ pub const Block = struct {
753
753
});
754
754
}
755
755
756
+ fn addReduce(block: *Block, operand: Air.Inst.Ref, operation: std.builtin.ReduceOp) !Air.Inst.Ref {
757
+ const sema = block.sema;
758
+ const zcu = sema.pt.zcu;
759
+ const vector_ty = sema.typeOf(operand);
760
+ switch (vector_ty.vectorLen(zcu)) {
761
+ 0 => unreachable,
762
+ 1 => return block.addBinOp(.array_elem_val, operand, .zero_usize),
763
+ else => {},
764
+ }
765
+ const allow_optimized = switch (vector_ty.childType(zcu).zigTypeTag(zcu)) {
766
+ .float => true,
767
+ .bool, .int => false,
768
+ else => unreachable,
769
+ };
770
+ return block.addInst(.{
771
+ .tag = if (allow_optimized and block.float_mode == .optimized) .reduce_optimized else .reduce,
772
+ .data = .{ .reduce = .{
773
+ .operand = operand,
774
+ .operation = operation,
775
+ } },
776
+ });
777
+ }
778
+
756
779
fn addAggregateInit(
757
780
block: *Block,
758
781
aggregate_ty: Type,
@@ -10307,10 +10330,7 @@ fn intCast(
10307
10330
const zeros = try sema.splat(operand_ty, try pt.intValue(operand_scalar_ty, 0));
10308
10331
const zero_inst = Air.internedToRef(zeros.toIntern());
10309
10332
const is_in_range = try block.addCmpVector(operand, zero_inst, .eq);
10310
- const all_in_range = try block.addInst(.{
10311
- .tag = .reduce,
10312
- .data = .{ .reduce = .{ .operand = is_in_range, .operation = .And } },
10313
- });
10333
+ const all_in_range = try block.addReduce(is_in_range, .And);
10314
10334
break :ok all_in_range;
10315
10335
} else ok: {
10316
10336
const zero_inst = Air.internedToRef((try pt.intValue(operand_ty, 0)).toIntern());
@@ -10374,13 +10394,7 @@ fn intCast(
10374
10394
10375
10395
const ok = if (is_vector) ok: {
10376
10396
const is_in_range = try block.addCmpVector(diff_unsigned, dest_range, .lte);
10377
- const all_in_range = try block.addInst(.{
10378
- .tag = if (block.float_mode == .optimized) .reduce_optimized else .reduce,
10379
- .data = .{ .reduce = .{
10380
- .operand = is_in_range,
10381
- .operation = .And,
10382
- } },
10383
- });
10397
+ const all_in_range = try block.addReduce(is_in_range, .And);
10384
10398
break :ok all_in_range;
10385
10399
} else ok: {
10386
10400
const is_in_range = try block.addBinOp(.cmp_lte, diff_unsigned, dest_range);
@@ -10391,13 +10405,7 @@ fn intCast(
10391
10405
} else {
10392
10406
const ok = if (is_vector) ok: {
10393
10407
const is_in_range = try block.addCmpVector(operand, dest_max, .lte);
10394
- const all_in_range = try block.addInst(.{
10395
- .tag = if (block.float_mode == .optimized) .reduce_optimized else .reduce,
10396
- .data = .{ .reduce = .{
10397
- .operand = is_in_range,
10398
- .operation = .And,
10399
- } },
10400
- });
10408
+ const all_in_range = try block.addReduce(is_in_range, .And);
10401
10409
break :ok all_in_range;
10402
10410
} else ok: {
10403
10411
const is_in_range = try block.addBinOp(.cmp_lte, operand, dest_max);
@@ -10413,13 +10421,7 @@ fn intCast(
10413
10421
const zero_val = try sema.splat(operand_ty, scalar_zero);
10414
10422
const zero_inst = Air.internedToRef(zero_val.toIntern());
10415
10423
const is_in_range = try block.addCmpVector(operand, zero_inst, .gte);
10416
- const all_in_range = try block.addInst(.{
10417
- .tag = if (block.float_mode == .optimized) .reduce_optimized else .reduce,
10418
- .data = .{ .reduce = .{
10419
- .operand = is_in_range,
10420
- .operation = .And,
10421
- } },
10422
- });
10424
+ const all_in_range = try block.addReduce(is_in_range, .And);
10423
10425
break :ok all_in_range;
10424
10426
} else ok: {
10425
10427
const zero_inst = Air.internedToRef((try pt.intValue(operand_ty, 0)).toIntern());
@@ -14330,13 +14332,7 @@ fn zirShl(
14330
14332
const ok = if (rhs_ty.zigTypeTag(zcu) == .vector) ok: {
14331
14333
const bit_count_inst = Air.internedToRef((try sema.splat(rhs_ty, bit_count_val)).toIntern());
14332
14334
const lt = try block.addCmpVector(rhs, bit_count_inst, .lt);
14333
- break :ok try block.addInst(.{
14334
- .tag = .reduce,
14335
- .data = .{ .reduce = .{
14336
- .operand = lt,
14337
- .operation = .And,
14338
- } },
14339
- });
14335
+ break :ok try block.addReduce(lt, .And);
14340
14336
} else ok: {
14341
14337
const bit_count_inst = Air.internedToRef(bit_count_val.toIntern());
14342
14338
break :ok try block.addBinOp(.cmp_lt, rhs, bit_count_inst);
@@ -14358,13 +14354,7 @@ fn zirShl(
14358
14354
});
14359
14355
const ov_bit = try sema.tupleFieldValByIndex(block, op_ov, 1, op_ov_tuple_ty);
14360
14356
const any_ov_bit = if (lhs_ty.zigTypeTag(zcu) == .vector)
14361
- try block.addInst(.{
14362
- .tag = if (block.float_mode == .optimized) .reduce_optimized else .reduce,
14363
- .data = .{ .reduce = .{
14364
- .operand = ov_bit,
14365
- .operation = .Or,
14366
- } },
14367
- })
14357
+ try block.addReduce(ov_bit, .Or)
14368
14358
else
14369
14359
ov_bit;
14370
14360
const zero_ov = Air.internedToRef((try pt.intValue(Type.u1, 0)).toIntern());
@@ -14490,13 +14480,7 @@ fn zirShr(
14490
14480
const ok = if (rhs_ty.zigTypeTag(zcu) == .vector) ok: {
14491
14481
const bit_count_inst = Air.internedToRef((try sema.splat(rhs_ty, bit_count_val)).toIntern());
14492
14482
const lt = try block.addCmpVector(rhs, bit_count_inst, .lt);
14493
- break :ok try block.addInst(.{
14494
- .tag = .reduce,
14495
- .data = .{ .reduce = .{
14496
- .operand = lt,
14497
- .operation = .And,
14498
- } },
14499
- });
14483
+ break :ok try block.addReduce(lt, .And);
14500
14484
} else ok: {
14501
14485
const bit_count_inst = Air.internedToRef(bit_count_val.toIntern());
14502
14486
break :ok try block.addBinOp(.cmp_lt, rhs, bit_count_inst);
@@ -14509,13 +14493,7 @@ fn zirShr(
14509
14493
14510
14494
const ok = if (rhs_ty.zigTypeTag(zcu) == .vector) ok: {
14511
14495
const eql = try block.addCmpVector(lhs, back, .eq);
14512
- break :ok try block.addInst(.{
14513
- .tag = if (block.float_mode == .optimized) .reduce_optimized else .reduce,
14514
- .data = .{ .reduce = .{
14515
- .operand = eql,
14516
- .operation = .And,
14517
- } },
14518
- });
14496
+ break :ok try block.addReduce(eql, .And);
14519
14497
} else try block.addBinOp(.cmp_eq, lhs, back);
14520
14498
try sema.addSafetyCheck(block, src, ok, .shr_overflow);
14521
14499
}
@@ -15565,16 +15543,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15565
15543
15566
15544
if (resolved_type.zigTypeTag(zcu) == .vector) {
15567
15545
const eql = try block.addCmpVector(result, floored, .eq);
15568
- break :ok try block.addInst(.{
15569
- .tag = switch (block.float_mode) {
15570
- .strict => .reduce,
15571
- .optimized => .reduce_optimized,
15572
- },
15573
- .data = .{ .reduce = .{
15574
- .operand = eql,
15575
- .operation = .And,
15576
- } },
15577
- });
15546
+ break :ok try block.addReduce(eql, .And);
15578
15547
} else {
15579
15548
const is_in_range = try block.addBinOp(switch (block.float_mode) {
15580
15549
.strict => .cmp_eq,
@@ -15594,13 +15563,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15594
15563
const zero_val = try sema.splat(resolved_type, scalar_zero);
15595
15564
const zero = Air.internedToRef(zero_val.toIntern());
15596
15565
const eql = try block.addCmpVector(remainder, zero, .eq);
15597
- break :ok try block.addInst(.{
15598
- .tag = .reduce,
15599
- .data = .{ .reduce = .{
15600
- .operand = eql,
15601
- .operation = .And,
15602
- } },
15603
- });
15566
+ break :ok try block.addReduce(eql, .And);
15604
15567
} else {
15605
15568
const zero = Air.internedToRef(scalar_zero.toIntern());
15606
15569
const is_in_range = try block.addBinOp(.cmp_eq, remainder, zero);
@@ -15829,13 +15792,7 @@ fn addDivIntOverflowSafety(
15829
15792
break :ok try block.addCmpVector(casted_rhs, neg_one_ref, .neq);
15830
15793
};
15831
15794
15832
- const ok = try block.addInst(.{
15833
- .tag = .reduce,
15834
- .data = .{ .reduce = .{
15835
- .operand = try block.addBinOp(.bool_or, lhs_ok, rhs_ok),
15836
- .operation = .And,
15837
- } },
15838
- });
15795
+ const ok = try block.addReduce(try block.addBinOp(.bool_or, lhs_ok, rhs_ok), .And);
15839
15796
try sema.addSafetyCheck(block, src, ok, .integer_overflow);
15840
15797
} else {
15841
15798
const lhs_ok: Air.Inst.Ref = if (maybe_lhs_val == null) ok: {
@@ -15886,13 +15843,7 @@ fn addDivByZeroSafety(
15886
15843
const zero_val = try sema.splat(resolved_type, scalar_zero);
15887
15844
const zero = Air.internedToRef(zero_val.toIntern());
15888
15845
const ok = try block.addCmpVector(casted_rhs, zero, .neq);
15889
- break :ok try block.addInst(.{
15890
- .tag = if (is_int) .reduce else .reduce_optimized,
15891
- .data = .{ .reduce = .{
15892
- .operand = ok,
15893
- .operation = .And,
15894
- } },
15895
- });
15846
+ break :ok try block.addReduce(ok, .And);
15896
15847
} else ok: {
15897
15848
const zero = Air.internedToRef(scalar_zero.toIntern());
15898
15849
break :ok try block.addBinOp(if (is_int) .cmp_neq else .cmp_neq_optimized, casted_rhs, zero);
@@ -16579,13 +16530,7 @@ fn analyzeArithmetic(
16579
16530
});
16580
16531
const ov_bit = try sema.tupleFieldValByIndex(block, op_ov, 1, op_ov_tuple_ty);
16581
16532
const any_ov_bit = if (resolved_type.zigTypeTag(zcu) == .vector)
16582
- try block.addInst(.{
16583
- .tag = if (block.float_mode == .optimized) .reduce_optimized else .reduce,
16584
- .data = .{ .reduce = .{
16585
- .operand = ov_bit,
16586
- .operation = .Or,
16587
- } },
16588
- })
16533
+ try block.addReduce(ov_bit, .Or)
16589
16534
else
16590
16535
ov_bit;
16591
16536
const zero_ov = Air.internedToRef((try pt.intValue(Type.u1, 0)).toIntern());
@@ -22406,13 +22351,7 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
22406
22351
const ok_pos = try block.addCmpVector(diff, Air.internedToRef((try sema.splat(operand_ty, try pt.floatValue(operand_scalar_ty, 1.0))).toIntern()), .lt);
22407
22352
const ok_neg = try block.addCmpVector(diff, Air.internedToRef((try sema.splat(operand_ty, try pt.floatValue(operand_scalar_ty, -1.0))).toIntern()), .gt);
22408
22353
const ok = try block.addBinOp(.bit_and, ok_pos, ok_neg);
22409
- break :ok try block.addInst(.{
22410
- .tag = .reduce,
22411
- .data = .{ .reduce = .{
22412
- .operand = ok,
22413
- .operation = .And,
22414
- } },
22415
- });
22354
+ break :ok try block.addReduce(ok, .And);
22416
22355
} else ok: {
22417
22356
const ok_pos = try block.addBinOp(if (block.float_mode == .optimized) .cmp_lt_optimized else .cmp_lt, diff, Air.internedToRef((try pt.floatValue(operand_ty, 1.0)).toIntern()));
22418
22357
const ok_neg = try block.addBinOp(if (block.float_mode == .optimized) .cmp_gt_optimized else .cmp_gt, diff, Air.internedToRef((try pt.floatValue(operand_ty, -1.0)).toIntern()));
@@ -22555,13 +22494,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
22555
22494
const is_non_zero = if (is_vector) all_non_zero: {
22556
22495
const zero_usize = Air.internedToRef((try sema.splat(operand_ty, .zero_usize)).toIntern());
22557
22496
const is_non_zero = try block.addCmpVector(operand_coerced, zero_usize, .neq);
22558
- break :all_non_zero try block.addInst(.{
22559
- .tag = .reduce,
22560
- .data = .{ .reduce = .{
22561
- .operand = is_non_zero,
22562
- .operation = .And,
22563
- } },
22564
- });
22497
+ break :all_non_zero try block.addReduce(is_non_zero, .And);
22565
22498
} else try block.addBinOp(.cmp_neq, operand_coerced, .zero_usize);
22566
22499
try sema.addSafetyCheck(block, src, is_non_zero, .cast_to_null);
22567
22500
}
@@ -22578,13 +22511,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
22578
22511
const is_aligned = if (is_vector) all_aligned: {
22579
22512
const splat_zero_usize = Air.internedToRef((try sema.splat(operand_ty, .zero_usize)).toIntern());
22580
22513
const is_aligned = try block.addCmpVector(remainder, splat_zero_usize, .eq);
22581
- break :all_aligned try block.addInst(.{
22582
- .tag = .reduce,
22583
- .data = .{ .reduce = .{
22584
- .operand = is_aligned,
22585
- .operation = .And,
22586
- } },
22587
- });
22514
+ break :all_aligned try block.addReduce(is_aligned, .And);
22588
22515
} else try block.addBinOp(.cmp_eq, remainder, .zero_usize);
22589
22516
try sema.addSafetyCheck(block, src, is_aligned, .incorrect_alignment);
22590
22517
}
@@ -24540,13 +24467,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
24540
24467
}
24541
24468
24542
24469
try sema.requireRuntimeBlock(block, block.nodeOffset(inst_data.src_node), operand_src);
24543
- return block.addInst(.{
24544
- .tag = if (block.float_mode == .optimized) .reduce_optimized else .reduce,
24545
- .data = .{ .reduce = .{
24546
- .operand = operand,
24547
- .operation = operation,
24548
- } },
24549
- });
24470
+ return block.addReduce(operand, operation);
24550
24471
}
24551
24472
24552
24473
fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
@@ -27324,13 +27245,7 @@ fn addSafetyCheckSentinelMismatch(
27324
27245
27325
27246
const ok = if (sentinel_ty.zigTypeTag(zcu) == .vector) ok: {
27326
27247
const eql = try parent_block.addCmpVector(expected_sentinel, actual_sentinel, .eq);
27327
- break :ok try parent_block.addInst(.{
27328
- .tag = .reduce,
27329
- .data = .{ .reduce = .{
27330
- .operand = eql,
27331
- .operation = .And,
27332
- } },
27333
- });
27248
+ break :ok try parent_block.addReduce(eql, .And);
27334
27249
} else ok: {
27335
27250
assert(sentinel_ty.isSelfComparable(zcu, true));
27336
27251
break :ok try parent_block.addBinOp(.cmp_eq, expected_sentinel, actual_sentinel);
0 commit comments