| author | |
| committer | |
| log | d486a7b81188ea1e027334c81589157efde2ad23 |
| tree | 364b3c5bd98adfd2650b292f8e67c52c0cb45dba |
| parent | 7605166426527c7d169ecad89d8de6799935f5ca |
The checks detecting such no-op branches (essentially instructions
that branch to the instruction immediately following the branch) were
tightened to catch more of these occurrences.9 files changed, 23 insertions(+), 25 deletions(-)
src/arch/arm/CodeGen.zig+23-12| ... | @@ -445,16 +445,17 @@ fn gen(self: *Self) !void { | ... | @@ -445,16 +445,17 @@ fn gen(self: *Self) !void { |
| 445 | }); | 445 | }); |
| 446 | 446 | ||
| 447 | // exitlude jumps | 447 | // exitlude jumps |
| 448 | const only_one_exitlude_jump = self.exitlude_jump_relocs.items.len == 1 and | 448 | if (self.exitlude_jump_relocs.items.len > 0 and |
| 449 | self.exitlude_jump_relocs.items[0] == self.mir_instructions.len - 1; | 449 | self.exitlude_jump_relocs.items[self.exitlude_jump_relocs.items.len - 1] == self.mir_instructions.len - 2) |
| 450 | if (only_one_exitlude_jump) { | 450 | { |
| 451 | // There is only one relocation. Hence, | 451 | // If the last Mir instruction (apart from the |
| 452 | // this relocation must be at the end of | 452 | // dbg_epilogue_begin) is the last exitlude jump |
| 453 | // the code. Therefore, we can just delete | 453 | // relocation (which would just jump one instruction |
| 454 | // the space initially reserved for the | 454 | // further), it can be safely removed |
| 455 | // jump | 455 | self.mir_instructions.orderedRemove(self.exitlude_jump_relocs.pop()); |
| 456 | self.mir_instructions.orderedRemove(self.exitlude_jump_relocs.items[0]); | 456 | } |
| 457 | } else for (self.exitlude_jump_relocs.items) |jmp_reloc| { | 457 | |
| 458 | for (self.exitlude_jump_relocs.items) |jmp_reloc| { | ||
| 458 | self.mir_instructions.set(jmp_reloc, .{ | 459 | self.mir_instructions.set(jmp_reloc, .{ |
| 459 | .tag = .b, | 460 | .tag = .b, |
| 460 | .data = .{ .inst = @intCast(u32, self.mir_instructions.len) }, | 461 | .data = .{ .inst = @intCast(u32, self.mir_instructions.len) }, |
| ... | @@ -3197,7 +3198,17 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3197,7 +3198,17 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void { |
| 3197 | const body = self.air.extra[extra.end..][0..extra.data.body_len]; | 3198 | const body = self.air.extra[extra.end..][0..extra.data.body_len]; |
| 3198 | try self.genBody(body); | 3199 | try self.genBody(body); |
| 3199 | 3200 | ||
| 3200 | for (self.blocks.getPtr(inst).?.relocs.items) |reloc| try self.performReloc(reloc); | 3201 | // relocations for `br` instructions |
| 3202 | const relocs = &self.blocks.getPtr(inst).?.relocs; | ||
| 3203 | if (relocs.items.len > 0 and relocs.items[relocs.items.len - 1] == self.mir_instructions.len - 1) { | ||
| 3204 | // If the last Mir instruction is the last relocation (which | ||
| 3205 | // would just jump one instruction further), it can be safely | ||
| 3206 | // removed | ||
| 3207 | self.mir_instructions.orderedRemove(relocs.pop()); | ||
| 3208 | } | ||
| 3209 | for (relocs.items) |reloc| { | ||
| 3210 | try self.performReloc(reloc); | ||
| 3211 | } | ||
| 3201 | 3212 | ||
| 3202 | const result = self.blocks.getPtr(inst).?.mcv; | 3213 | const result = self.blocks.getPtr(inst).?.mcv; |
| 3203 | return self.finishAir(inst, result, .{ .none, .none, .none }); | 3214 | return self.finishAir(inst, result, .{ .none, .none, .none }); |
| ... | @@ -3952,7 +3963,7 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3952,7 +3963,7 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { |
| 3952 | const ptr_ty = self.air.typeOf(ty_op.operand); | 3963 | const ptr_ty = self.air.typeOf(ty_op.operand); |
| 3953 | const ptr = try self.resolveInst(ty_op.operand); | 3964 | const ptr = try self.resolveInst(ty_op.operand); |
| 3954 | const array_ty = ptr_ty.childType(); | 3965 | const array_ty = ptr_ty.childType(); |
| 3955 | const array_len = @intCast(u32, array_ty.arrayLenIncludingSentinel()); | 3966 | const array_len = @intCast(u32, array_ty.arrayLen()); |
| 3956 | 3967 | ||
| 3957 | const stack_offset = try self.allocMem(inst, 8, 8); | 3968 | const stack_offset = try self.allocMem(inst, 8, 8); |
| 3958 | try self.genSetStack(ptr_ty, stack_offset + 4, ptr); | 3969 | try self.genSetStack(ptr_ty, stack_offset + 4, ptr); |
test/behavior/align.zig-1| ... | @@ -271,7 +271,6 @@ test "runtime known array index has best alignment possible" { | ... | @@ -271,7 +271,6 @@ test "runtime known array index has best alignment possible" { |
| 271 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | 271 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO |
| 272 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 272 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 273 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | 273 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 274 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 275 | 274 | ||
| 276 | // take full advantage of over-alignment | 275 | // take full advantage of over-alignment |
| 277 | var array align(4) = [_]u8{ 1, 2, 3, 4 }; | 276 | var array align(4) = [_]u8{ 1, 2, 3, 4 }; |
test/behavior/cast.zig-3| ... | @@ -223,8 +223,6 @@ test "@intToEnum passed a comptime_int to an enum with one item" { | ... | @@ -223,8 +223,6 @@ test "@intToEnum passed a comptime_int to an enum with one item" { |
| 223 | } | 223 | } |
| 224 | 224 | ||
| 225 | test "@intCast to u0 and use the result" { | 225 | test "@intCast to u0 and use the result" { |
| 226 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | ||
| 227 | |||
| 228 | const S = struct { | 226 | const S = struct { |
| 229 | fn doTheTest(zero: u1, one: u1, bigzero: i32) !void { | 227 | fn doTheTest(zero: u1, one: u1, bigzero: i32) !void { |
| 230 | try expect((one << @intCast(u0, bigzero)) == 1); | 228 | try expect((one << @intCast(u0, bigzero)) == 1); |
| ... | @@ -818,7 +816,6 @@ test "peer resolution of string literals" { | ... | @@ -818,7 +816,6 @@ test "peer resolution of string literals" { |
| 818 | test "peer cast [:x]T to []T" { | 816 | test "peer cast [:x]T to []T" { |
| 819 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 817 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 820 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | 818 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 821 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 822 | 819 | ||
| 823 | const S = struct { | 820 | const S = struct { |
| 824 | fn doTheTest() !void { | 821 | fn doTheTest() !void { |
test/behavior/error.zig-1| ... | @@ -211,7 +211,6 @@ fn testErrorSetType() !void { | ... | @@ -211,7 +211,6 @@ fn testErrorSetType() !void { |
| 211 | test "explicit error set cast" { | 211 | test "explicit error set cast" { |
| 212 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 212 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 213 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | 213 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 214 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 215 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 214 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 216 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 215 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 217 | 216 |
test/behavior/floatop.zig-1| ... | @@ -24,7 +24,6 @@ test "floating point comparisons" { | ... | @@ -24,7 +24,6 @@ test "floating point comparisons" { |
| 24 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 24 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 25 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | 25 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 26 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 26 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 27 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 28 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 27 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 29 | 28 | ||
| 30 | try testFloatComparisons(); | 29 | try testFloatComparisons(); |
test/behavior/inttoptr.zig-1| ... | @@ -2,7 +2,6 @@ const builtin = @import("builtin"); | ... | @@ -2,7 +2,6 @@ const builtin = @import("builtin"); |
| 2 | 2 | ||
| 3 | test "casting integer address to function pointer" { | 3 | test "casting integer address to function pointer" { |
| 4 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 4 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 5 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | ||
| 6 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 5 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 7 | 6 | ||
| 8 | addressToFunction(); | 7 | addressToFunction(); |
test/behavior/math.zig-3| ... | @@ -313,7 +313,6 @@ test "xor" { | ... | @@ -313,7 +313,6 @@ test "xor" { |
| 313 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | 313 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 314 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 314 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 315 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 315 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 316 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 317 | 316 | ||
| 318 | try test_xor(); | 317 | try test_xor(); |
| 319 | comptime try test_xor(); | 318 | comptime try test_xor(); |
| ... | @@ -565,7 +564,6 @@ test "bit shift a u1" { | ... | @@ -565,7 +564,6 @@ test "bit shift a u1" { |
| 565 | test "truncating shift right" { | 564 | test "truncating shift right" { |
| 566 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 565 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 567 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 566 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 568 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 569 | 567 | ||
| 570 | try testShrTrunc(maxInt(u16)); | 568 | try testShrTrunc(maxInt(u16)); |
| 571 | comptime try testShrTrunc(maxInt(u16)); | 569 | comptime try testShrTrunc(maxInt(u16)); |
| ... | @@ -735,7 +733,6 @@ test "overflow arithmetic with u0 values" { | ... | @@ -735,7 +733,6 @@ test "overflow arithmetic with u0 values" { |
| 735 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 733 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 736 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 734 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 737 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 735 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 738 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 739 | 736 | ||
| 740 | var result: u0 = undefined; | 737 | var result: u0 = undefined; |
| 741 | try expect(!@addWithOverflow(u0, 0, 0, &result)); | 738 | try expect(!@addWithOverflow(u0, 0, 0, &result)); |
test/behavior/slice.zig-1| ... | @@ -191,7 +191,6 @@ test "comptime pointer cast array and then slice" { | ... | @@ -191,7 +191,6 @@ test "comptime pointer cast array and then slice" { |
| 191 | test "slicing zero length array" { | 191 | test "slicing zero length array" { |
| 192 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 192 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 193 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | 193 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO |
| 194 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | ||
| 195 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 194 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 196 | 195 | ||
| 197 | const s1 = ""[0..]; | 196 | const s1 = ""[0..]; |
test/behavior/switch.zig-2| ... | @@ -190,7 +190,6 @@ test "switch with disjoint range" { | ... | @@ -190,7 +190,6 @@ test "switch with disjoint range" { |
| 190 | } | 190 | } |
| 191 | 191 | ||
| 192 | test "switch variable for range and multiple prongs" { | 192 | test "switch variable for range and multiple prongs" { |
| 193 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 194 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 193 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 195 | 194 | ||
| 196 | const S = struct { | 195 | const S = struct { |
| ... | @@ -358,7 +357,6 @@ fn returnsFalse() bool { | ... | @@ -358,7 +357,6 @@ fn returnsFalse() bool { |
| 358 | } | 357 | } |
| 359 | } | 358 | } |
| 360 | test "switch on const enum with var" { | 359 | test "switch on const enum with var" { |
| 361 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 362 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 360 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 363 | 361 | ||
| 364 | try expect(!returnsFalse()); | 362 | try expect(!returnsFalse()); |