Skip to content

Another MBB reordering bug #62

@gergoerdi

Description

@gergoerdi

This one seems similar to #49. I don't have a shrunk example yet.

LLVM IR:

target triple = "avr-atmel-none"

%str_slice = type { i8*, i16 }
%"core::option::Option<chip8_engine::opcodes::Op>" = type { i16, [0 x i16], [2 x i16] }
%"chip8_engine::machine::Machine" = type { i16, [0 x i8], i16, [0 x i8], [16 x i8], [0 x i8] }

@str.0 = internal constant [68 x i8] c"/home/cactus/prog/rust/avr/stripped8/chip8-engine-avr/src/machine.rs"
@panic_bounds_check_loc.1 = internal unnamed_addr constant { %str_slice, i32 } { %str_slice { i8* getelementptr inbounds ([68 x i8], [68 x i8]* @str.0, i32 0, i32 0), i16 68 }, i32 41 }, align 4
@panic_bounds_check_loc.2 = internal unnamed_addr constant { %str_slice, i32 } { %str_slice { i8* getelementptr inbounds ([68 x i8], [68 x i8]* @str.0, i32 0, i32 0), i16 68 }, i32 36 }, align 4
@"_ZN38_$LT$core..option..Option$LT$T$GT$$GT$6unwrap14_MSG_FILE_LINE17h1ad372c436feeebeE" = external global { i32, [0 x i8], %str_slice, [0 x i8], %str_slice, [0 x i8] }

; Function Attrs: noinline norecurse nounwind uwtable
define internal fastcc void @_ZN9chip8_avr3spi5setup17he6a9e8a8cb3a0461E() unnamed_addr #1 {
start:
  %0 = load volatile i8, i8* inttoptr (i16 37 to i8*), align 1
  %1 = or i8 %0, 4
  store volatile i8 %1, i8* inttoptr (i16 37 to i8*), align 1
  %2 = load volatile i8, i8* inttoptr (i16 36 to i8*), align 4
  %3 = or i8 %2, 44
  store volatile i8 %3, i8* inttoptr (i16 36 to i8*), align 4
  %4 = load volatile i8, i8* inttoptr (i16 36 to i8*), align 4
  %5 = and i8 %4, -17
  store volatile i8 %5, i8* inttoptr (i16 36 to i8*), align 4
  store volatile i8 80, i8* inttoptr (i16 76 to i8*), align 4
  ret void
}

; Function Attrs: noreturn nounwind uwtable
define void @main() unnamed_addr {
start:
  %_12.i = alloca %"core::option::Option<chip8_engine::opcodes::Op>", align 8
  %machine = alloca %"chip8_engine::machine::Machine", align 8
  tail call fastcc void @_ZN9chip8_avr3spi5setup17he6a9e8a8cb3a0461E() #6
  %0 = bitcast %"chip8_engine::machine::Machine"* %machine to i8*
  call void @_ZN12chip8_engine7machine7Machine3new17h5e85f0933e39358cE(%"chip8_engine::machine::Machine"* noalias nocapture nonnull sret dereferenceable(20) %machine) #6
  %1 = getelementptr inbounds %"chip8_engine::machine::Machine", %"chip8_engine::machine::Machine"* %machine, i16 0, i32 2
  %2 = load i16, i16* %1, align 2
  %3 = lshr i16 %2, 8
  %4 = trunc i16 %3 to i8
  store volatile i8 %4, i8* inttoptr (i16 78 to i8*), align 2
  br label %bb2.i

bb2.i:                                            ; preds = %bb2.i, %start
  %5 = load volatile i8, i8* inttoptr (i16 77 to i8*), align 1
  %6 = icmp sgt i8 %5, -1
  br i1 %6, label %bb2.i, label %_ZN9chip8_avr3spi4sync17hb1a38c1bcef3b0caE.exit

_ZN9chip8_avr3spi4sync17hb1a38c1bcef3b0caE.exit:  ; preds = %bb2.i
  %7 = load volatile i8, i8* inttoptr (i16 78 to i8*), align 2
  %8 = trunc i16 %2 to i8
  store volatile i8 %8, i8* inttoptr (i16 78 to i8*), align 2
  br label %bb2.i1

bb2.i1:                                           ; preds = %bb2.i1, %_ZN9chip8_avr3spi4sync17hb1a38c1bcef3b0caE.exit
  %9 = load volatile i8, i8* inttoptr (i16 77 to i8*), align 1
  %10 = icmp sgt i8 %9, -1
  br i1 %10, label %bb2.i1, label %_ZN9chip8_avr3spi4sync17hb1a38c1bcef3b0caE.exit2

_ZN9chip8_avr3spi4sync17hb1a38c1bcef3b0caE.exit2: ; preds = %bb2.i1
  %11 = load volatile i8, i8* inttoptr (i16 78 to i8*), align 2
  store volatile i8 66, i8* inttoptr (i16 78 to i8*), align 2
  br label %bb2.i3

bb2.i3:                                           ; preds = %bb2.i3, %_ZN9chip8_avr3spi4sync17hb1a38c1bcef3b0caE.exit2
  %12 = load volatile i8, i8* inttoptr (i16 77 to i8*), align 1
  %13 = icmp sgt i8 %12, -1
  br i1 %13, label %bb2.i3, label %_ZN9chip8_avr3spi4sync17hb1a38c1bcef3b0caE.exit4

_ZN9chip8_avr3spi4sync17hb1a38c1bcef3b0caE.exit4: ; preds = %bb2.i3
  %14 = load volatile i8, i8* inttoptr (i16 78 to i8*), align 2
  store volatile i8 66, i8* inttoptr (i16 78 to i8*), align 2
  br label %bb2.i5

bb2.i5:                                           ; preds = %bb2.i5, %_ZN9chip8_avr3spi4sync17hb1a38c1bcef3b0caE.exit4
  %15 = load volatile i8, i8* inttoptr (i16 77 to i8*), align 1
  %16 = icmp sgt i8 %15, -1
  br i1 %16, label %bb2.i5, label %_ZN9chip8_avr3spi4sync17hb1a38c1bcef3b0caE.exit6

_ZN9chip8_avr3spi4sync17hb1a38c1bcef3b0caE.exit6: ; preds = %bb2.i5
  %17 = load volatile i8, i8* inttoptr (i16 78 to i8*), align 2
  store volatile i8 66, i8* inttoptr (i16 78 to i8*), align 2
  br label %bb2.i7

bb2.i7:                                           ; preds = %bb2.i7, %_ZN9chip8_avr3spi4sync17hb1a38c1bcef3b0caE.exit6
  %18 = load volatile i8, i8* inttoptr (i16 77 to i8*), align 1
  %19 = icmp sgt i8 %18, -1
  br i1 %19, label %bb2.i7, label %_ZN9chip8_avr3spi4sync17hb1a38c1bcef3b0caE.exit8

; spi over
  
_ZN9chip8_avr3spi4sync17hb1a38c1bcef3b0caE.exit8: ; preds = %bb2.i7
  %20 = load volatile i8, i8* inttoptr (i16 78 to i8*), align 2
  %21 = add i16 %2, 2
  store i16 %21, i16* %1, align 2
  %22 = bitcast %"core::option::Option<chip8_engine::opcodes::Op>"* %_12.i to i8*
  call void @_ZN12chip8_engine7opcodes6decode17h08b0a6212958bb22E(%"core::option::Option<chip8_engine::opcodes::Op>"* noalias nocapture nonnull sret dereferenceable(6) %_12.i, i8 0, i8 0) #6
  %self.sroa.0.0..sroa_idx.i.i = getelementptr inbounds %"core::option::Option<chip8_engine::opcodes::Op>", %"core::option::Option<chip8_engine::opcodes::Op>"* %_12.i, i16 0, i32 0
  %self.sroa.0.0.copyload.i.i11 = load i16, i16* %self.sroa.0.0..sroa_idx.i.i, align 8
  %cond.i.i12 = icmp eq i16 %self.sroa.0.0.copyload.i.i11, 0
  br label %"_ZN38_$LT$core..option..Option$LT$T$GT$$GT$6unwrap17hf2429150be5ad2daE.exit.i.lr.ph"

"_ZN38_$LT$core..option..Option$LT$T$GT$$GT$6unwrap17hf2429150be5ad2daE.exit.i.lr.ph": ; preds = %_ZN9chip8_avr3spi4sync17hb1a38c1bcef3b0caE.exit8
  %self.sroa.4.0..sroa_idx.i.i = getelementptr inbounds %"core::option::Option<chip8_engine::opcodes::Op>", %"core::option::Option<chip8_engine::opcodes::Op>"* %_12.i, i16 0, i32 2
  %23 = bitcast [2 x i16]* %self.sroa.4.0..sroa_idx.i.i to i32*
  %24 = getelementptr inbounds %"chip8_engine::machine::Machine", %"chip8_engine::machine::Machine"* %machine, i16 0, i32 0
  br label %"_ZN38_$LT$core..option..Option$LT$T$GT$$GT$6unwrap17hf2429150be5ad2daE.exit.i"

"_ZN38_$LT$core..option..Option$LT$T$GT$$GT$6unwrap17hf2429150be5ad2daE.exit.i": ; preds = %"_ZN38_$LT$core..option..Option$LT$T$GT$$GT$6unwrap17hf2429150be5ad2daE.exit.i.lr.ph", %bb7.backedge
  %25 = load i32, i32* %23, align 2
  %_11.sroa.4.0.extract.shift.i = lshr i32 %25, 8
  %_11.sroa.4.0.extract.trunc.i = trunc i32 %_11.sroa.4.0.extract.shift.i to i8
  %_11.sroa.6.0.extract.shift.i = lshr i32 %25, 16
  %trunc.i = trunc i32 %25 to i2
  switch i2 %trunc.i, label %bb7.i [
    i2 0, label %bb5.i
    i2 1, label %bb6.i
  ]

bb5.i:                                            ; preds = %"_ZN38_$LT$core..option..Option$LT$T$GT$$GT$6unwrap17hf2429150be5ad2daE.exit.i"
  %26 = trunc i32 %_11.sroa.6.0.extract.shift.i to i16
  store i16 %26, i16* %24, align 8
  br label %bb7.backedge

bb7.backedge:                                     ; preds = %bb5.i, %bb9.i, %"_ZN75_$LT$chip8_avr..Board$u20$as$u20$chip8_engine..peripherals..Peripherals$GT$12scan_key_row17haa3ed42a3d3a5068E.exit.i", %bb17.i
  %27 = load i16, i16* %1, align 2
  %28 = add i16 %27, 2
  store i16 %28, i16* %1, align 2
  call void @_ZN12chip8_engine7opcodes6decode17h08b0a6212958bb22E(%"core::option::Option<chip8_engine::opcodes::Op>"* noalias nocapture nonnull sret dereferenceable(6) %_12.i, i8 0, i8 0) #6
  %self.sroa.0.0.copyload.i.i = load i16, i16* %self.sroa.0.0..sroa_idx.i.i, align 8
  br label %"_ZN38_$LT$core..option..Option$LT$T$GT$$GT$6unwrap17hf2429150be5ad2daE.exit.i"

bb6.i:                                            ; preds = %"_ZN38_$LT$core..option..Option$LT$T$GT$$GT$6unwrap17hf2429150be5ad2daE.exit.i"
  %29 = trunc i32 %_11.sroa.4.0.extract.shift.i to i16
  %30 = and i16 %29, 255
  %31 = icmp ult i8 %_11.sroa.4.0.extract.trunc.i, 16
  br i1 %31, label %bb9.i, label %panic1.i

bb7.i:                                            ; preds = %"_ZN38_$LT$core..option..Option$LT$T$GT$$GT$6unwrap17hf2429150be5ad2daE.exit.i"
  %_11.sroa.6.sroa.0.0.extract.trunc.i = trunc i32 %_11.sroa.6.0.extract.shift.i to i8
  %32 = trunc i32 %_11.sroa.6.0.extract.shift.i to i16
  %33 = and i16 %32, 255
  %34 = icmp ult i8 %_11.sroa.6.sroa.0.0.extract.trunc.i, 16
  br i1 %34, label %bb11.i, label %panic.i

bb9.i:                                            ; preds = %bb6.i
  %35 = load i16, i16* %24, align 8
  %36 = getelementptr inbounds %"chip8_engine::machine::Machine", %"chip8_engine::machine::Machine"* %machine, i16 0, i32 4, i16 %30
  %37 = load i8, i8* %36, align 1
  %38 = zext i8 %37 to i16
  %39 = add i16 %38, %35
  %40 = icmp ugt i16 %39, 4095
  call void @_ZN12chip8_engine7machine7Machine8set_flag17h6f9b6a49847d3e95E(%"chip8_engine::machine::Machine"* nonnull dereferenceable(20) %machine, i1 zeroext %40) #6
  %41 = and i16 %39, 4095
  store i16 %41, i16* %24, align 8
  br label %bb7.backedge

bb11.i:                                           ; preds = %bb7.i
  %42 = getelementptr inbounds %"chip8_engine::machine::Machine", %"chip8_engine::machine::Machine"* %machine, i16 0, i32 4, i16 %33
  %43 = load i8, i8* %42, align 1
  %44 = call i16 @_ZN12chip8_engine7machine7Machine10key_coords17h88e9d2ab5a0d2adaE(i8 %43) #6
  %abi_cast.sroa.0.0.extract.trunc.i = trunc i16 %44 to i8
  %abi_cast.sroa.4.0.extract.shift.i = lshr i16 %44, 8
  %abi_cast.sroa.4.0.extract.trunc.i = trunc i16 %abi_cast.sroa.4.0.extract.shift.i to i8
  switch i8 %abi_cast.sroa.0.0.extract.trunc.i, label %bb6.i.i.i [
    i8 0, label %bb1.i.i.i
    i8 1, label %bb2.i.i.i
    i8 2, label %bb3.i.i.i
    i8 3, label %bb4.i.i.i
  ]

bb1.i.i.i:                                        ; preds = %bb11.i
  %45 = load volatile i8, i8* inttoptr (i16 40 to i8*), align 8
  %46 = and i8 %45, -3
  br label %bb6.sink.split.i.i.i

bb2.i.i.i:                                        ; preds = %bb11.i
  %47 = load volatile i8, i8* inttoptr (i16 40 to i8*), align 8
  %48 = and i8 %47, -2
  br label %bb6.sink.split.i.i.i

bb3.i.i.i:                                        ; preds = %bb11.i
  %49 = load volatile i8, i8* inttoptr (i16 37 to i8*), align 1
  %50 = and i8 %49, -5
  br label %bb6.sink.split.i.i.i

bb4.i.i.i:                                        ; preds = %bb11.i
  %51 = load volatile i8, i8* inttoptr (i16 37 to i8*), align 1
  %52 = and i8 %51, -3
  br label %bb6.sink.split.i.i.i

bb6.sink.split.i.i.i:                             ; preds = %bb4.i.i.i, %bb3.i.i.i, %bb2.i.i.i, %bb1.i.i.i
  %.sink7.i.i.i = phi i8* [ inttoptr (i16 40 to i8*), %bb1.i.i.i ], [ inttoptr (i16 40 to i8*), %bb2.i.i.i ], [ inttoptr (i16 37 to i8*), %bb3.i.i.i ], [ inttoptr (i16 37 to i8*), %bb4.i.i.i ]
  %.sink.i.i.i = phi i8 [ %46, %bb1.i.i.i ], [ %48, %bb2.i.i.i ], [ %50, %bb3.i.i.i ], [ %52, %bb4.i.i.i ]
  store volatile i8 %.sink.i.i.i, i8* %.sink7.i.i.i, align 1
  br label %bb6.i.i.i

bb6.i.i.i:                                        ; preds = %bb6.sink.split.i.i.i, %bb11.i
  call void asm "NOP", ""() #6
  br label %bb17.i.i.i

bb17.i.i.i:                                       ; preds = %bb17.i.i.i, %bb6.i.i.i
  %buf.019.i.i.i = phi i8 [ 0, %bb6.i.i.i ], [ %53, %bb17.i.i.i ]
  %success_count.018.i.i.i = phi i32 [ 0, %bb6.i.i.i ], [ %.17.i.i.i, %bb17.i.i.i ]
  %53 = load volatile i8, i8* inttoptr (i16 38 to i8*), align 2
  %54 = icmp eq i8 %buf.019.i.i.i, %53
  %55 = add i32 %success_count.018.i.i.i, 1
  %.17.i.i.i = select i1 %54, i32 %55, i32 0
  %56 = icmp slt i32 %.17.i.i.i, 20
  br i1 %56, label %bb17.i.i.i, label %"_ZN75_$LT$chip8_avr..Board$u20$as$u20$chip8_engine..peripherals..Peripherals$GT$12scan_key_row17haa3ed42a3d3a5068E.exit.i"

"_ZN75_$LT$chip8_avr..Board$u20$as$u20$chip8_engine..peripherals..Peripherals$GT$12scan_key_row17haa3ed42a3d3a5068E.exit.i": ; preds = %bb17.i.i.i
  %phitmp.le.i.i.i = xor i8 %53, -1
  %57 = load volatile i8, i8* inttoptr (i16 40 to i8*), align 8
  %58 = or i8 %57, 3
  store volatile i8 %58, i8* inttoptr (i16 40 to i8*), align 8
  %59 = load volatile i8, i8* inttoptr (i16 37 to i8*), align 1
  %60 = or i8 %59, 6
  store volatile i8 %60, i8* inttoptr (i16 37 to i8*), align 1
  %61 = lshr i8 %phitmp.le.i.i.i, 5
  %62 = and i8 %61, 1
  %63 = lshr i8 %phitmp.le.i.i.i, 3
  %64 = and i8 %63, 2
  %65 = or i8 %64, %62
  %66 = lshr i8 %phitmp.le.i.i.i, 1
  %67 = and i8 %66, 4
  %68 = or i8 %65, %67
  %69 = shl i8 %phitmp.le.i.i.i, 1
  %70 = and i8 %69, 8
  %.lobit.i.i.i = or i8 %68, %70
  %71 = xor i8 %.lobit.i.i.i, 15
  %72 = and i8 %abi_cast.sroa.4.0.extract.trunc.i, 7
  %73 = shl i8 1, %72
  %74 = and i8 %71, %73
  %75 = icmp ne i8 %74, 0
  %cond2.i = icmp eq i8 %_11.sroa.4.0.extract.trunc.i, 0
  %tmp.i = xor i1 %cond2.i, %75
  br i1 %tmp.i, label %bb7.backedge, label %bb17.i

bb17.i:                                           ; preds = %"_ZN75_$LT$chip8_avr..Board$u20$as$u20$chip8_engine..peripherals..Peripherals$GT$12scan_key_row17haa3ed42a3d3a5068E.exit.i"
  %76 = load i16, i16* %1, align 2
  %77 = add i16 %76, 2
  store i16 %77, i16* %1, align 2
  br label %bb7.backedge

panic.i:                                          ; preds = %bb7.i
  call void @_ZN4core9panicking18panic_bounds_check17hf101292d002856afE({ %str_slice, [0 x i8], i32, [0 x i8] }* bitcast ({ %str_slice, i32 }* @panic_bounds_check_loc.1 to { %str_slice, [0 x i8], i32, [0 x i8] }*), i16 %33, i16 16) #6
  unreachable

panic1.i:                                         ; preds = %bb6.i
  call void @_ZN4core9panicking18panic_bounds_check17hf101292d002856afE({ %str_slice, [0 x i8], i32, [0 x i8] }* bitcast ({ %str_slice, i32 }* @panic_bounds_check_loc.2 to { %str_slice, [0 x i8], i32, [0 x i8] }*), i16 %30, i16 16) #6
  unreachable

done:
  br label %done
}

declare void @_ZN12chip8_engine7opcodes6decode17h08b0a6212958bb22E(%"core::option::Option<chip8_engine::opcodes::Op>"* noalias nocapture sret dereferenceable(6), i8, i8) unnamed_addr

; Function Attrs: cold noinline noreturn
declare void @_ZN4core9panicking18panic_bounds_check17hf101292d002856afE({ %str_slice, [0 x i8], i32, [0 x i8] }* noalias readonly dereferenceable(8), i16, i16) unnamed_addr #4

declare i16 @_ZN12chip8_engine7machine7Machine10key_coords17h88e9d2ab5a0d2adaE(i8) unnamed_addr

declare void @_ZN12chip8_engine7machine7Machine8set_flag17h6f9b6a49847d3e95E(%"chip8_engine::machine::Machine"* dereferenceable(20), i1 zeroext) unnamed_addr

; Function Attrs: cold noinline noreturn
declare void @_ZN4core9panicking5panic17h19294ca45466d235E({ i32, [0 x i8], %str_slice, [0 x i8], %str_slice, [0 x i8] }* noalias readonly dereferenceable(12)) unnamed_addr #4

; Function Attrs: noinline
declare void @_ZN12chip8_engine7machine7Machine3new17h5e85f0933e39358cE(%"chip8_engine::machine::Machine"* noalias nocapture sret dereferenceable(20)) unnamed_addr #5

In the generated assembly, main starts with %start as expected, but then falls through to %"_ZN75_$LT$chip8_avr..Board$u20$as$u20$chip8_engine..peripherals..Peripherals$GT$12scan_key_row17haa3ed42a3d3a5068E.exit.i" instead of %bb2.i:

main:                                   ; @main
; BB#0:                                 ; %start
	push	r28
	push	r29
	push	r2
	push	r3
	push	r4
	push	r5
	push	r6
	push	r7
	push	r8
	push	r9
	push	r10
	push	r11
	push	r12
	push	r13
	push	r14
	push	r15
	push	r16
	push	r17
	in	r28, 61
	in	r29, 62
	sbiw	r28, 30
	in	r0, 63
	cli
	out	62, r29
	out	63, r0
	out	61, r28
	call	_ZN9chip8_avr3spi5setup17he6a9e8a8cb3a0461E
	movw	r16, r28
	subi	r16, 255
	sbci	r17, 255
	mov	r24, r16
	mov	r25, r17
	call	_ZN12chip8_engine7machine7Machine3new17h5e85f0933e39358cE
	ldd	r24, Y+3
	ldd	r25, Y+4
	out	46, r25
	ori	r16, 2
LBB1_1:                                 ; %"_ZN75_$LT$chip8_avr..Board$u20$as$u20$chip8_engine..peripherals..Peripherals$GT$12scan_key_row17haa3ed42a3d3a5068E.exit.i"
	lsl	r21
	subi	r25, 1
	breq	.+2
	rjmp	LBB1_1
	rjmp	LBB1_2
LBB1_6:                                 ; %bb2.i
	in	r18, 45
	tst	r18
	brmi	.+2
	rjmp	LBB1_6
; BB#7:                                 ; %_ZN9chip8_avr3spi4sync17hb1a38c1bcef3b0caE.exit
	in	r18, 46
	out	46, r24

Metadata

Metadata

Assignees

No one assigned

    Labels

    has-llvm-commitThis issue should be fixed in upstream LLVMhas-reduced-testcaseA small LLVM IR file exists that demonstrates the problem

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions