1; RUN: llc -O1 < %s -march=avr | FileCheck %s 2 3; This test ensures that the Select8/Select16 expansion 4; pass inserts an unconditional branch to the previous adjacent 5; basic block when inserting new basic blocks when the 6; prior block has a fallthrough. 7; 8; Before this bug was fixed, Select8/Select16 expansion 9; would leave a dangling fallthrough to an undefined block. 10; 11; The BranchFolding pass would later rearrange the basic 12; blocks based on predecessor/successor list assumptions 13; which were made incorrect due to the invalid Select 14; expansion. 15 16; More information in 17; https://github.com/avr-rust/rust/issues/123. 18 19%UInt8 = type <{ i8 }> 20%UInt32 = type <{ i32 }> 21%Sb = type <{ i1 }> 22 23@delayFactor = hidden global %UInt8 zeroinitializer, align 1 24@delay = hidden global %UInt32 zeroinitializer, align 4 25@flag = hidden global %Sb zeroinitializer, align 1 26 27declare void @eeprom_write(i16, i8) 28 29; CHECK-LABEL: update_register 30define hidden void @update_register(i8 %arg, i8 %arg1) { 31entry: 32 ; CHECK: push [[PRELUDER:r[0-9]+]] 33 ; CHECK: cpi r24, 7 34 switch i8 %arg, label %bb7 [ 35 i8 6, label %bb 36 i8 7, label %bb6 37 ] 38 39; CHECK-NOT: ret 40bb: ; preds = %entry 41 %tmp = icmp ugt i8 %arg1, 90 42 %tmp2 = icmp ult i8 %arg1, 5 43 %. = select i1 %tmp2, i8 5, i8 %arg1 44 %tmp3 = select i1 %tmp, i8 90, i8 %. 45 ; CHECK: sts delayFactor, r{{[0-9]+}} 46 store i8 %tmp3, i8* getelementptr inbounds (%UInt8, %UInt8* @delayFactor, i64 0, i32 0), align 1 47 %tmp4 = zext i8 %tmp3 to i32 48 %tmp5 = mul nuw nsw i32 %tmp4, 100 49 ; CHECK: sts delay+3, r{{[0-9]+}} 50 ; CHECK-NEXT: sts delay+2, r{{[0-9]+}} 51 ; CHECK-NEXT: sts delay+1, r{{[0-9]+}} 52 ; CHECK-NEXT: sts delay, r{{[0-9]+}} 53 store i32 %tmp5, i32* getelementptr inbounds (%UInt32, %UInt32* @delay, i64 0, i32 0), align 4 54 tail call void @eeprom_write(i16 34, i8 %tmp3) 55 br label %bb7 56 57bb6: ; preds = %entry 58 %not. = icmp ne i8 %arg1, 0 59 %.2 = zext i1 %not. to i8 60 store i1 %not., i1* getelementptr inbounds (%Sb, %Sb* @flag, i64 0, i32 0), align 1 61 62 ; CHECK: call eeprom_write 63 tail call void @eeprom_write(i16 35, i8 %.2) 64 br label %bb7 65 66 ; CHECK: LBB0_{{[0-9]+}} 67 ; CHECK: pop [[PRELUDER]] 68 ; CHECK-NEXT: ret 69bb7: ; preds = %bb6, %bb, %entry 70 ret void 71} 72; CHECK-NOT: LBB0_{{[0-9]+}}: 73; CHECK-LABEL: .Lfunc_end0 74; CHECK: .size update_register, .Lfunc_end0-update_register 75