Skip to content

Instantly share code, notes, and snippets.

@dylanmckay
Last active August 29, 2015 14:24
Show Gist options
  • Save dylanmckay/3bbbabb912d16e1a39f1 to your computer and use it in GitHub Desktop.
Save dylanmckay/3bbbabb912d16e1a39f1 to your computer and use it in GitHub Desktop.

Revisions

  1. Dylan McKay revised this gist Jul 9, 2015. 4 changed files with 926 additions and 4 deletions.
    114 changes: 113 additions & 1 deletion HardwareSerial0.ll
    Original file line number Diff line number Diff line change
    @@ -1 +1,113 @@
    this file failed compilation with clang
    ; ModuleID = 'HardwareSerial0.cpp'
    target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-i64:8:8-f32:8:8-f64:8:8-n8"
    target triple = "avr"

    %class.HardwareSerial = type { %class.Stream, i8*, i8*, i8*, i8*, i8*, i8*, i8, i8, i8, i8, i8, [64 x i8], [64 x i8], i8 }
    %class.Stream = type { %class.Print, i32, i32 }
    %class.Print = type { i32 (...)**, i16 }

    @Serial = global %class.HardwareSerial zeroinitializer, align 2
    @_ZTV14HardwareSerial = external unnamed_addr constant [8 x i8*]
    @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_HardwareSerial0.cpp, i8* null }]
    @llvm.used = appending global [2 x i8*] [i8* bitcast (void ()* @__vector_18 to i8*), i8* bitcast (void ()* @__vector_19 to i8*)], section "llvm.metadata"

    ; Function Attrs: noinline nounwind
    define avr_signalcc void @__vector_18() #0 {
    entry:
    %0 = load i8*, i8** getelementptr inbounds (%class.HardwareSerial, %class.HardwareSerial* @Serial, i16 0, i32 3), align 2, !tbaa !1
    %1 = load volatile i8, i8* %0, align 1, !tbaa !7
    %and.i = and i8 %1, 4
    %tobool.i = icmp eq i8 %and.i, 0
    br i1 %tobool.i, label %if.then.i, label %_ZN14HardwareSerial16_rx_complete_irqEv.exit

    if.then.i: ; preds = %entry
    %2 = load i8*, i8** getelementptr inbounds (%class.HardwareSerial, %class.HardwareSerial* @Serial, i16 0, i32 6), align 2, !tbaa !8
    %3 = load volatile i8, i8* %2, align 1, !tbaa !7
    %4 = load volatile i8, i8* getelementptr inbounds (%class.HardwareSerial, %class.HardwareSerial* @Serial, i16 0, i32 8), align 1, !tbaa !9
    %add.i = add i8 %4, 1
    %rem.i = and i8 %add.i, 63
    %5 = load volatile i8, i8* getelementptr inbounds (%class.HardwareSerial, %class.HardwareSerial* @Serial, i16 0, i32 9), align 2, !tbaa !10
    %cmp.i = icmp eq i8 %rem.i, %5
    br i1 %cmp.i, label %_ZN14HardwareSerial16_rx_complete_irqEv.exit, label %if.then.6.i

    if.then.6.i: ; preds = %if.then.i
    %6 = load volatile i8, i8* getelementptr inbounds (%class.HardwareSerial, %class.HardwareSerial* @Serial, i16 0, i32 8), align 1, !tbaa !9
    %idxprom.i = zext i8 %6 to i16
    %arrayidx.i = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* @Serial, i16 0, i32 12, i16 %idxprom.i
    store i8 %3, i8* %arrayidx.i, align 1, !tbaa !7
    store volatile i8 %rem.i, i8* getelementptr inbounds (%class.HardwareSerial, %class.HardwareSerial* @Serial, i16 0, i32 8), align 1, !tbaa !9
    br label %_ZN14HardwareSerial16_rx_complete_irqEv.exit

    _ZN14HardwareSerial16_rx_complete_irqEv.exit: ; preds = %entry, %if.then.i, %if.then.6.i
    ret void
    }

    ; Function Attrs: noinline
    define avr_signalcc void @__vector_19() #1 {
    entry:
    tail call void @_ZN14HardwareSerial17_tx_udr_empty_irqEv(%class.HardwareSerial* nonnull @Serial)
    ret void
    }

    declare void @_ZN14HardwareSerial17_tx_udr_empty_irqEv(%class.HardwareSerial*) #2

    define zeroext i1 @_Z17Serial0_availablev() #2 {
    entry:
    %call = tail call i16 @_ZN14HardwareSerial9availableEv(%class.HardwareSerial* nonnull @Serial)
    %tobool = icmp ne i16 %call, 0
    ret i1 %tobool
    }

    declare i16 @_ZN14HardwareSerial9availableEv(%class.HardwareSerial*) #2

    ; Function Attrs: nounwind
    define internal void @_GLOBAL__sub_I_HardwareSerial0.cpp() #3 {
    entry:
    store i16 0, i16* getelementptr inbounds (%class.HardwareSerial, %class.HardwareSerial* @Serial, i16 0, i32 0, i32 0, i32 1), align 2, !tbaa !11
    store i32 1000, i32* getelementptr inbounds (%class.HardwareSerial, %class.HardwareSerial* @Serial, i16 0, i32 0, i32 1), align 2, !tbaa !14
    store i32 (...)** bitcast (i8** getelementptr inbounds ([8 x i8*], [8 x i8*]* @_ZTV14HardwareSerial, i16 0, i16 2) to i32 (...)**), i32 (...)*** getelementptr inbounds (%class.HardwareSerial, %class.HardwareSerial* @Serial, i16 0, i32 0, i32 0, i32 0), align 2, !tbaa !17
    store i8* inttoptr (i16 197 to i8*), i8** getelementptr inbounds (%class.HardwareSerial, %class.HardwareSerial* @Serial, i16 0, i32 1), align 2, !tbaa !19
    store i8* inttoptr (i16 196 to i8*), i8** getelementptr inbounds (%class.HardwareSerial, %class.HardwareSerial* @Serial, i16 0, i32 2), align 2, !tbaa !20
    store i8* inttoptr (i16 192 to i8*), i8** getelementptr inbounds (%class.HardwareSerial, %class.HardwareSerial* @Serial, i16 0, i32 3), align 2, !tbaa !1
    store i8* inttoptr (i16 193 to i8*), i8** getelementptr inbounds (%class.HardwareSerial, %class.HardwareSerial* @Serial, i16 0, i32 4), align 2, !tbaa !21
    store i8* inttoptr (i16 194 to i8*), i8** getelementptr inbounds (%class.HardwareSerial, %class.HardwareSerial* @Serial, i16 0, i32 5), align 2, !tbaa !22
    store i8* inttoptr (i16 198 to i8*), i8** getelementptr inbounds (%class.HardwareSerial, %class.HardwareSerial* @Serial, i16 0, i32 6), align 2, !tbaa !8
    store volatile i8 0, i8* getelementptr inbounds (%class.HardwareSerial, %class.HardwareSerial* @Serial, i16 0, i32 8), align 1, !tbaa !9
    store volatile i8 0, i8* getelementptr inbounds (%class.HardwareSerial, %class.HardwareSerial* @Serial, i16 0, i32 9), align 2, !tbaa !10
    store volatile i8 0, i8* getelementptr inbounds (%class.HardwareSerial, %class.HardwareSerial* @Serial, i16 0, i32 10), align 1, !tbaa !23
    store volatile i8 0, i8* getelementptr inbounds (%class.HardwareSerial, %class.HardwareSerial* @Serial, i16 0, i32 11), align 2, !tbaa !24
    ret void
    }

    attributes #0 = { noinline nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #1 = { noinline "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #2 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #3 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }

    !llvm.ident = !{!0}

    !0 = !{!"clang version 3.7.0 (https://github.com/llvm-mirror/clang.git 287e62c84a1ccd74fbca46bfc13e364e314d4b41) (https://github.com/llvm-mirror/llvm.git d98a9c55e1add3cb93d7424a86828510d0557a2c)"}
    !1 = !{!2, !3, i64 16}
    !2 = !{!"_ZTS14HardwareSerial", !3, i64 12, !3, i64 14, !3, i64 16, !3, i64 18, !3, i64 20, !3, i64 22, !6, i64 24, !4, i64 25, !4, i64 26, !4, i64 27, !4, i64 28, !4, i64 29, !4, i64 93}
    !3 = !{!"any pointer", !4, i64 0}
    !4 = !{!"omnipotent char", !5, i64 0}
    !5 = !{!"Simple C/C++ TBAA"}
    !6 = !{!"bool", !4, i64 0}
    !7 = !{!4, !4, i64 0}
    !8 = !{!2, !3, i64 22}
    !9 = !{!2, !4, i64 25}
    !10 = !{!2, !4, i64 26}
    !11 = !{!12, !13, i64 2}
    !12 = !{!"_ZTS5Print", !13, i64 2}
    !13 = !{!"int", !4, i64 0}
    !14 = !{!15, !16, i64 4}
    !15 = !{!"_ZTS6Stream", !16, i64 4, !16, i64 8}
    !16 = !{!"long", !4, i64 0}
    !17 = !{!18, !18, i64 0}
    !18 = !{!"vtable pointer", !5, i64 0}
    !19 = !{!2, !3, i64 12}
    !20 = !{!2, !3, i64 14}
    !21 = !{!2, !3, i64 18}
    !22 = !{!2, !3, i64 20}
    !23 = !{!2, !4, i64 27}
    !24 = !{!2, !4, i64 28}
    465 changes: 464 additions & 1 deletion Tone.ll
    Original file line number Diff line number Diff line change
    @@ -1 +1,464 @@
    this file failed compilation with clang
    ; ModuleID = 'Tone.cpp'
    target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-i64:8:8-f32:8:8-f64:8:8-n8"
    target triple = "avr"

    @timer0_toggle_count = global i32 0, align 2
    @timer0_pin_port = global i8* null, align 2
    @timer0_pin_mask = global i8 0, align 1
    @timer1_toggle_count = global i32 0, align 2
    @timer1_pin_port = global i8* null, align 2
    @timer1_pin_mask = global i8 0, align 1
    @timer2_toggle_count = global i32 0, align 2
    @timer2_pin_port = global i8* null, align 2
    @timer2_pin_mask = global i8 0, align 1
    @_ZL9tone_pins = internal unnamed_addr global [1 x i8] c"\FF", align 1
    @_ZL21tone_pin_to_timer_PGM = internal constant [1 x i8] c"\02", section ".progmem", align 1
    @port_to_output_PGM = external constant [0 x i16], align 2
    @digital_pin_to_port_PGM = external constant [0 x i8], align 1
    @digital_pin_to_bit_mask_PGM = external constant [0 x i8], align 1
    @llvm.used = appending global [1 x i8*] [i8* bitcast (void ()* @__vector_7 to i8*)], section "llvm.metadata"

    define void @_Z4tonehjm(i8 zeroext %_pin, i16 %frequency, i32 %duration) #0 {
    entry:
    %0 = load i8, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @_ZL9tone_pins, i16 0, i16 0), align 1, !tbaa !1
    %cmp2.i = icmp eq i8 %0, %_pin
    br i1 %cmp2.i, label %cleanup.i, label %for.inc.i

    for.inc.i: ; preds = %entry
    %cmp11.i = icmp eq i8 %0, -1
    br i1 %cmp11.i, label %cleanup.23.i, label %if.end.118

    cleanup.i: ; preds = %entry
    %1 = tail call i8 asm sideeffect "lpm\0A\09mov $0, r0\0A\09", "=r,z,~{r0}"(i16 ptrtoint ([1 x i8]* @_ZL21tone_pin_to_timer_PGM to i16)) #3, !srcloc !4
    br label %_ZL9toneBeginh.exit

    cleanup.23.i: ; preds = %for.inc.i
    store i8 %_pin, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @_ZL9tone_pins, i16 0, i16 0), align 1, !tbaa !1
    %2 = tail call i8 asm sideeffect "lpm\0A\09mov $0, r0\0A\09", "=r,z,~{r0}"(i16 ptrtoint ([1 x i8]* @_ZL21tone_pin_to_timer_PGM to i16)) #3, !srcloc !5
    %cmp26.i = icmp eq i8 %2, -1
    br i1 %cmp26.i, label %if.end.118, label %if.then.27.i

    if.then.27.i: ; preds = %cleanup.23.i
    %conv25.i = sext i8 %2 to i16
    switch i16 %conv25.i, label %_ZL9toneBeginh.exit [
    i16 0, label %sw.bb.i
    i16 1, label %sw.bb.56.i
    i16 2, label %sw.bb.86.i
    ]

    sw.bb.i: ; preds = %if.then.27.i
    store volatile i8 0, i8* inttoptr (i16 68 to i8*), align 4, !tbaa !1
    store volatile i8 0, i8* inttoptr (i16 69 to i8*), align 1, !tbaa !1
    %3 = load volatile i8, i8* inttoptr (i16 68 to i8*), align 4, !tbaa !1
    %or.i = or i8 %3, 2
    store volatile i8 %or.i, i8* inttoptr (i16 68 to i8*), align 4, !tbaa !1
    %4 = load volatile i8, i8* inttoptr (i16 69 to i8*), align 1, !tbaa !1
    %or32.i = or i8 %4, 1
    store volatile i8 %or32.i, i8* inttoptr (i16 69 to i8*), align 1, !tbaa !1
    %conv38.i = zext i8 %_pin to i16
    %add.ptr39.i = getelementptr inbounds [0 x i8], [0 x i8]* @digital_pin_to_port_PGM, i16 0, i16 %conv38.i
    %5 = ptrtoint i8* %add.ptr39.i to i16
    %6 = tail call i8 asm sideeffect "lpm\0A\09mov $0, r0\0A\09", "=r,z,~{r0}"(i16 %5) #3, !srcloc !6
    %conv43.i = zext i8 %6 to i16
    %add.ptr44.i = getelementptr inbounds [0 x i16], [0 x i16]* @port_to_output_PGM, i16 0, i16 %conv43.i
    %7 = ptrtoint i16* %add.ptr44.i to i16
    %8 = tail call { i16, i16 } asm sideeffect "lpm\0A\09mov ${0:A}, r0\0A\09adiw r30, 1\0A\09lpm\0A\09mov ${0:B}, r0\0A\09", "=r,=z,1,~{r0}"(i16 %7) #3, !srcloc !7
    %asmresult.i = extractvalue { i16, i16 } %8, 0
    %9 = inttoptr i16 %asmresult.i to i8*
    store i8* %9, i8** @timer0_pin_port, align 2, !tbaa !8
    %add.ptr52.i = getelementptr inbounds [0 x i8], [0 x i8]* @digital_pin_to_bit_mask_PGM, i16 0, i16 %conv38.i
    %10 = ptrtoint i8* %add.ptr52.i to i16
    %11 = tail call i8 asm sideeffect "lpm\0A\09mov $0, r0\0A\09", "=r,z,~{r0}"(i16 %10) #3, !srcloc !10
    store volatile i8 %11, i8* @timer0_pin_mask, align 1, !tbaa !1
    br label %_ZL9toneBeginh.exit

    sw.bb.56.i: ; preds = %if.then.27.i
    store volatile i8 0, i8* inttoptr (i16 128 to i8*), align 128, !tbaa !1
    store volatile i8 0, i8* inttoptr (i16 129 to i8*), align 1, !tbaa !1
    %12 = load volatile i8, i8* inttoptr (i16 129 to i8*), align 1, !tbaa !1
    %or58.i = or i8 %12, 8
    store volatile i8 %or58.i, i8* inttoptr (i16 129 to i8*), align 1, !tbaa !1
    %13 = load volatile i8, i8* inttoptr (i16 129 to i8*), align 1, !tbaa !1
    %or61.i = or i8 %13, 1
    store volatile i8 %or61.i, i8* inttoptr (i16 129 to i8*), align 1, !tbaa !1
    %conv67.i = zext i8 %_pin to i16
    %add.ptr68.i = getelementptr inbounds [0 x i8], [0 x i8]* @digital_pin_to_port_PGM, i16 0, i16 %conv67.i
    %14 = ptrtoint i8* %add.ptr68.i to i16
    %15 = tail call i8 asm sideeffect "lpm\0A\09mov $0, r0\0A\09", "=r,z,~{r0}"(i16 %14) #3, !srcloc !11
    %conv72.i = zext i8 %15 to i16
    %add.ptr73.i = getelementptr inbounds [0 x i16], [0 x i16]* @port_to_output_PGM, i16 0, i16 %conv72.i
    %16 = ptrtoint i16* %add.ptr73.i to i16
    %17 = tail call { i16, i16 } asm sideeffect "lpm\0A\09mov ${0:A}, r0\0A\09adiw r30, 1\0A\09lpm\0A\09mov ${0:B}, r0\0A\09", "=r,=z,1,~{r0}"(i16 %16) #3, !srcloc !12
    %asmresult76.i = extractvalue { i16, i16 } %17, 0
    %18 = inttoptr i16 %asmresult76.i to i8*
    store i8* %18, i8** @timer1_pin_port, align 2, !tbaa !8
    %add.ptr82.i = getelementptr inbounds [0 x i8], [0 x i8]* @digital_pin_to_bit_mask_PGM, i16 0, i16 %conv67.i
    %19 = ptrtoint i8* %add.ptr82.i to i16
    %20 = tail call i8 asm sideeffect "lpm\0A\09mov $0, r0\0A\09", "=r,z,~{r0}"(i16 %19) #3, !srcloc !13
    store volatile i8 %20, i8* @timer1_pin_mask, align 1, !tbaa !1
    br label %_ZL9toneBeginh.exit

    sw.bb.86.i: ; preds = %if.then.27.i
    store volatile i8 0, i8* inttoptr (i16 176 to i8*), align 16, !tbaa !1
    store volatile i8 0, i8* inttoptr (i16 177 to i8*), align 1, !tbaa !1
    %21 = load volatile i8, i8* inttoptr (i16 176 to i8*), align 16, !tbaa !1
    %or88.i = or i8 %21, 2
    store volatile i8 %or88.i, i8* inttoptr (i16 176 to i8*), align 16, !tbaa !1
    %22 = load volatile i8, i8* inttoptr (i16 177 to i8*), align 1, !tbaa !1
    %or91.i = or i8 %22, 1
    store volatile i8 %or91.i, i8* inttoptr (i16 177 to i8*), align 1, !tbaa !1
    %conv97.i = zext i8 %_pin to i16
    %add.ptr98.i = getelementptr inbounds [0 x i8], [0 x i8]* @digital_pin_to_port_PGM, i16 0, i16 %conv97.i
    %23 = ptrtoint i8* %add.ptr98.i to i16
    %24 = tail call i8 asm sideeffect "lpm\0A\09mov $0, r0\0A\09", "=r,z,~{r0}"(i16 %23) #3, !srcloc !14
    %conv102.i = zext i8 %24 to i16
    %add.ptr103.i = getelementptr inbounds [0 x i16], [0 x i16]* @port_to_output_PGM, i16 0, i16 %conv102.i
    %25 = ptrtoint i16* %add.ptr103.i to i16
    %26 = tail call { i16, i16 } asm sideeffect "lpm\0A\09mov ${0:A}, r0\0A\09adiw r30, 1\0A\09lpm\0A\09mov ${0:B}, r0\0A\09", "=r,=z,1,~{r0}"(i16 %25) #3, !srcloc !15
    %asmresult106.i = extractvalue { i16, i16 } %26, 0
    %27 = inttoptr i16 %asmresult106.i to i8*
    store i8* %27, i8** @timer2_pin_port, align 2, !tbaa !8
    %add.ptr112.i = getelementptr inbounds [0 x i8], [0 x i8]* @digital_pin_to_bit_mask_PGM, i16 0, i16 %conv97.i
    %28 = ptrtoint i8* %add.ptr112.i to i16
    %29 = tail call i8 asm sideeffect "lpm\0A\09mov $0, r0\0A\09", "=r,z,~{r0}"(i16 %28) #3, !srcloc !16
    store volatile i8 %29, i8* @timer2_pin_mask, align 1, !tbaa !1
    br label %_ZL9toneBeginh.exit

    _ZL9toneBeginh.exit: ; preds = %cleanup.i, %if.then.27.i, %sw.bb.i, %sw.bb.56.i, %sw.bb.86.i
    %retval.1.i = phi i8 [ %1, %cleanup.i ], [ %2, %sw.bb.i ], [ %2, %sw.bb.56.i ], [ %2, %sw.bb.86.i ], [ %2, %if.then.27.i ]
    %conv = sext i8 %retval.1.i to i16
    %cmp = icmp sgt i8 %retval.1.i, -1
    br i1 %cmp, label %if.then, label %if.end.118

    if.then: ; preds = %_ZL9toneBeginh.exit
    tail call void @pinMode(i8 zeroext %_pin, i8 zeroext 1)
    %cmp2 = icmp eq i8 %retval.1.i, 0
    switch i8 %retval.1.i, label %if.else.75 [
    i8 2, label %if.then.5
    i8 0, label %if.then.5
    ]

    if.then.5: ; preds = %if.then, %if.then
    %conv6 = zext i16 %frequency to i32
    %div = udiv i32 16000000, %conv6
    %div7 = lshr i32 %div, 1
    %sub = add nsw i32 %div7, -1
    %cmp8 = icmp ugt i32 %sub, 255
    %extract.t172 = trunc i32 %sub to i8
    %extract.t178 = trunc i32 %sub to i16
    br i1 %cmp8, label %if.then.9, label %if.end.70

    if.then.9: ; preds = %if.then.5
    %div13 = lshr i32 %div, 4
    %sub14 = add nsw i32 %div13, -1
    %cmp16 = icmp eq i8 %retval.1.i, 2
    %cmp17 = icmp ugt i32 %sub14, 255
    %or.cond = and i1 %cmp16, %cmp17
    %div22 = lshr i32 %div, 6
    %sub23 = add nsw i32 %div22, -1
    %ocr.0 = select i1 %or.cond, i32 %sub23, i32 %sub14
    %prescalarbits.0 = select i1 %or.cond, i8 3, i8 2
    %cmp24 = icmp ugt i32 %ocr.0, 255
    %extract.t171 = trunc i32 %ocr.0 to i8
    %extract.t177 = trunc i32 %ocr.0 to i16
    br i1 %cmp24, label %if.then.25, label %if.end.70

    if.then.25: ; preds = %if.then.9
    %div29 = lshr i32 %div, 7
    %sub30 = add nsw i32 %div29, -1
    %conv33 = select i1 %cmp2, i8 3, i8 4
    %cmp37 = icmp ugt i32 %sub30, 255
    %or.cond119 = and i1 %cmp16, %cmp37
    %div42 = lshr i32 %div, 8
    %sub43 = add nsw i32 %div42, -1
    %ocr.1 = select i1 %or.cond119, i32 %sub43, i32 %sub30
    %prescalarbits.1 = select i1 %or.cond119, i8 5, i8 %conv33
    %cmp45 = icmp ugt i32 %ocr.1, 255
    %extract.t170 = trunc i32 %ocr.1 to i8
    %extract.t176 = trunc i32 %ocr.1 to i16
    br i1 %cmp45, label %if.then.46, label %if.end.70

    if.then.46: ; preds = %if.then.25
    %div50 = lshr i32 %div, 9
    %sub51 = add nsw i32 %div50, -1
    %conv55 = select i1 %cmp2, i8 4, i8 6
    %cmp56 = icmp ugt i32 %sub51, 255
    %extract.t169 = trunc i32 %sub51 to i8
    %extract.t175 = trunc i32 %sub51 to i16
    br i1 %cmp56, label %if.then.57, label %if.end.70

    if.then.57: ; preds = %if.then.46
    %div61 = lshr i32 %div, 11
    %sub62 = add nsw i32 %div61, -1
    %conv66 = select i1 %cmp2, i8 5, i8 7
    %extract.t168 = trunc i32 %sub62 to i8
    %extract.t174 = trunc i32 %sub62 to i16
    br label %if.end.70

    if.end.70: ; preds = %if.then.9, %if.then.46, %if.then.57, %if.then.25, %if.then.5
    %ocr.2.off0 = phi i8 [ %extract.t168, %if.then.57 ], [ %extract.t169, %if.then.46 ], [ %extract.t170, %if.then.25 ], [ %extract.t171, %if.then.9 ], [ %extract.t172, %if.then.5 ]
    %ocr.2.off0173 = phi i16 [ %extract.t174, %if.then.57 ], [ %extract.t175, %if.then.46 ], [ %extract.t176, %if.then.25 ], [ %extract.t177, %if.then.9 ], [ %extract.t178, %if.then.5 ]
    %prescalarbits.2 = phi i8 [ %conv66, %if.then.57 ], [ %conv55, %if.then.46 ], [ %prescalarbits.1, %if.then.25 ], [ %prescalarbits.0, %if.then.9 ], [ 1, %if.then.5 ]
    br i1 %cmp2, label %if.then.73, label %if.else

    if.then.73: ; preds = %if.end.70
    store volatile i8 %prescalarbits.2, i8* inttoptr (i16 69 to i8*), align 1, !tbaa !1
    br label %if.end.95

    if.else: ; preds = %if.end.70
    store volatile i8 %prescalarbits.2, i8* inttoptr (i16 177 to i8*), align 1, !tbaa !1
    br label %if.end.95

    if.else.75: ; preds = %if.then
    %conv76 = zext i16 %frequency to i32
    %div77 = udiv i32 16000000, %conv76
    %div78 = lshr i32 %div77, 1
    %sub79 = add nsw i32 %div78, -1
    %cmp80 = icmp ugt i32 %sub79, 65535
    %extract.t164 = trunc i32 %sub79 to i8
    %extract.t167 = trunc i32 %sub79 to i16
    br i1 %cmp80, label %if.then.81, label %if.end.87

    if.then.81: ; preds = %if.else.75
    %div85 = lshr i32 %div77, 7
    %sub86 = add nsw i32 %div85, -1
    %extract.t163 = trunc i32 %sub86 to i8
    %extract.t166 = trunc i32 %sub86 to i16
    br label %if.end.87

    if.end.87: ; preds = %if.then.81, %if.else.75
    %ocr.3.off0 = phi i8 [ %extract.t163, %if.then.81 ], [ %extract.t164, %if.else.75 ]
    %ocr.3.off0165 = phi i16 [ %extract.t166, %if.then.81 ], [ %extract.t167, %if.else.75 ]
    %prescalarbits.3 = phi i8 [ 3, %if.then.81 ], [ 1, %if.else.75 ]
    %cmp89 = icmp eq i8 %retval.1.i, 1
    br i1 %cmp89, label %if.then.90, label %if.end.95

    if.then.90: ; preds = %if.end.87
    %30 = load volatile i8, i8* inttoptr (i16 129 to i8*), align 1, !tbaa !1
    %and = and i8 %30, -8
    %or = or i8 %and, %prescalarbits.3
    store volatile i8 %or, i8* inttoptr (i16 129 to i8*), align 1, !tbaa !1
    br label %if.end.95

    if.end.95: ; preds = %if.end.87, %if.then.90, %if.then.73, %if.else
    %ocr.4.off0 = phi i8 [ %ocr.2.off0, %if.then.73 ], [ %ocr.2.off0, %if.else ], [ %ocr.3.off0, %if.then.90 ], [ %ocr.3.off0, %if.end.87 ]
    %ocr.4.off0158 = phi i16 [ %ocr.2.off0173, %if.then.73 ], [ %ocr.2.off0173, %if.else ], [ %ocr.3.off0165, %if.then.90 ], [ %ocr.3.off0165, %if.end.87 ]
    %cmp96 = icmp eq i32 %duration, 0
    br i1 %cmp96, label %if.end.102, label %if.then.97

    if.then.97: ; preds = %if.end.95
    %mul = shl i16 %frequency, 1
    %conv98 = zext i16 %mul to i32
    %mul99 = mul i32 %conv98, %duration
    %div100 = udiv i32 %mul99, 1000
    br label %if.end.102

    if.end.102: ; preds = %if.end.95, %if.then.97
    %toggle_count.0 = phi i32 [ %div100, %if.then.97 ], [ -1, %if.end.95 ]
    switch i16 %conv, label %if.end.118 [
    i16 0, label %sw.bb
    i16 1, label %sw.bb.108
    i16 2, label %sw.bb.113
    ]

    sw.bb: ; preds = %if.end.102
    store volatile i8 %ocr.4.off0, i8* inttoptr (i16 71 to i8*), align 1, !tbaa !1
    store volatile i32 %toggle_count.0, i32* @timer0_toggle_count, align 2, !tbaa !17
    %31 = load volatile i8, i8* inttoptr (i16 110 to i8*), align 2, !tbaa !1
    %or106 = or i8 %31, 2
    store volatile i8 %or106, i8* inttoptr (i16 110 to i8*), align 2, !tbaa !1
    br label %if.end.118

    sw.bb.108: ; preds = %if.end.102
    store volatile i16 %ocr.4.off0158, i16* inttoptr (i16 136 to i16*), align 8, !tbaa !19
    store volatile i32 %toggle_count.0, i32* @timer1_toggle_count, align 2, !tbaa !17
    %32 = load volatile i8, i8* inttoptr (i16 111 to i8*), align 1, !tbaa !1
    %or111 = or i8 %32, 2
    store volatile i8 %or111, i8* inttoptr (i16 111 to i8*), align 1, !tbaa !1
    br label %if.end.118

    sw.bb.113: ; preds = %if.end.102
    store volatile i8 %ocr.4.off0, i8* inttoptr (i16 179 to i8*), align 1, !tbaa !1
    store volatile i32 %toggle_count.0, i32* @timer2_toggle_count, align 2, !tbaa !17
    %33 = load volatile i8, i8* inttoptr (i16 112 to i8*), align 16, !tbaa !1
    %or116 = or i8 %33, 2
    store volatile i8 %or116, i8* inttoptr (i16 112 to i8*), align 16, !tbaa !1
    br label %if.end.118

    if.end.118: ; preds = %for.inc.i, %cleanup.23.i, %sw.bb, %sw.bb.108, %sw.bb.113, %if.end.102, %_ZL9toneBeginh.exit
    ret void
    }

    declare void @pinMode(i8 zeroext, i8 zeroext) #0

    ; Function Attrs: nounwind
    define void @_Z12disableTimerh(i8 zeroext %_timer) #1 {
    entry:
    switch i8 %_timer, label %sw.epilog [
    i8 0, label %sw.bb
    i8 1, label %sw.bb.1
    i8 2, label %sw.bb.4
    ]

    sw.bb: ; preds = %entry
    store volatile i8 0, i8* inttoptr (i16 110 to i8*), align 2, !tbaa !1
    br label %sw.epilog

    sw.bb.1: ; preds = %entry
    %0 = load volatile i8, i8* inttoptr (i16 111 to i8*), align 1, !tbaa !1
    %and = and i8 %0, -3
    store volatile i8 %and, i8* inttoptr (i16 111 to i8*), align 1, !tbaa !1
    br label %sw.epilog

    sw.bb.4: ; preds = %entry
    %1 = load volatile i8, i8* inttoptr (i16 112 to i8*), align 16, !tbaa !1
    %and6 = and i8 %1, -3
    store volatile i8 %and6, i8* inttoptr (i16 112 to i8*), align 16, !tbaa !1
    store volatile i8 1, i8* inttoptr (i16 176 to i8*), align 16, !tbaa !1
    %2 = load volatile i8, i8* inttoptr (i16 177 to i8*), align 1, !tbaa !1
    %and9 = and i8 %2, -8
    %or = or i8 %and9, 4
    store volatile i8 %or, i8* inttoptr (i16 177 to i8*), align 1, !tbaa !1
    store volatile i8 0, i8* inttoptr (i16 179 to i8*), align 1, !tbaa !1
    br label %sw.epilog

    sw.epilog: ; preds = %entry, %sw.bb.4, %sw.bb.1, %sw.bb
    ret void
    }

    define void @_Z6noToneh(i8 zeroext %_pin) #0 {
    entry:
    %0 = load i8, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @_ZL9tone_pins, i16 0, i16 0), align 1, !tbaa !1
    %cmp2 = icmp eq i8 %0, %_pin
    br i1 %cmp2, label %for.inc, label %_Z12disableTimerh.exit

    sw.bb.i: ; preds = %for.inc
    store volatile i8 0, i8* inttoptr (i16 110 to i8*), align 2, !tbaa !1
    br label %_Z12disableTimerh.exit

    sw.bb.1.i: ; preds = %for.inc
    %1 = load volatile i8, i8* inttoptr (i16 111 to i8*), align 1, !tbaa !1
    %and.i = and i8 %1, -3
    store volatile i8 %and.i, i8* inttoptr (i16 111 to i8*), align 1, !tbaa !1
    br label %_Z12disableTimerh.exit

    sw.bb.4.i: ; preds = %for.inc
    %2 = load volatile i8, i8* inttoptr (i16 112 to i8*), align 16, !tbaa !1
    %and6.i = and i8 %2, -3
    store volatile i8 %and6.i, i8* inttoptr (i16 112 to i8*), align 16, !tbaa !1
    store volatile i8 1, i8* inttoptr (i16 176 to i8*), align 16, !tbaa !1
    %3 = load volatile i8, i8* inttoptr (i16 177 to i8*), align 1, !tbaa !1
    %and9.i = and i8 %3, -8
    %or.i = or i8 %and9.i, 4
    store volatile i8 %or.i, i8* inttoptr (i16 177 to i8*), align 1, !tbaa !1
    store volatile i8 0, i8* inttoptr (i16 179 to i8*), align 1, !tbaa !1
    br label %_Z12disableTimerh.exit

    _Z12disableTimerh.exit: ; preds = %entry, %for.inc, %sw.bb.i, %sw.bb.1.i, %sw.bb.4.i
    tail call void @digitalWrite(i8 zeroext %_pin, i8 zeroext 0)
    ret void

    for.inc: ; preds = %entry
    %4 = tail call i8 asm sideeffect "lpm\0A\09mov $0, r0\0A\09", "=r,z,~{r0}"(i16 ptrtoint ([1 x i8]* @_ZL21tone_pin_to_timer_PGM to i16)) #3, !srcloc !21
    store i8 -1, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @_ZL9tone_pins, i16 0, i16 0), align 1, !tbaa !1
    switch i8 %4, label %_Z12disableTimerh.exit [
    i8 0, label %sw.bb.i
    i8 1, label %sw.bb.1.i
    i8 2, label %sw.bb.4.i
    ]
    }

    declare void @digitalWrite(i8 zeroext, i8 zeroext) #0

    ; Function Attrs: noinline
    define avr_signalcc void @__vector_7() #2 {
    entry:
    %0 = load volatile i32, i32* @timer2_toggle_count, align 2, !tbaa !17
    %cmp = icmp eq i32 %0, 0
    br i1 %cmp, label %for.inc.i, label %if.then

    if.then: ; preds = %entry
    %1 = load volatile i8, i8* @timer2_pin_mask, align 1, !tbaa !1
    %2 = load i8*, i8** @timer2_pin_port, align 2, !tbaa !8
    %3 = load volatile i8, i8* %2, align 1, !tbaa !1
    %xor6 = xor i8 %3, %1
    store volatile i8 %xor6, i8* %2, align 1, !tbaa !1
    %4 = load volatile i32, i32* @timer2_toggle_count, align 2, !tbaa !17
    %cmp3 = icmp sgt i32 %4, 0
    br i1 %cmp3, label %if.then.4, label %if.end.5

    if.then.4: ; preds = %if.then
    %5 = load volatile i32, i32* @timer2_toggle_count, align 2, !tbaa !17
    %dec = add nsw i32 %5, -1
    store volatile i32 %dec, i32* @timer2_toggle_count, align 2, !tbaa !17
    br label %if.end.5

    sw.bb.i.i: ; preds = %for.inc.i
    store volatile i8 0, i8* inttoptr (i16 110 to i8*), align 2, !tbaa !1
    br label %_Z6noToneh.exit

    sw.bb.1.i.i: ; preds = %for.inc.i
    %6 = load volatile i8, i8* inttoptr (i16 111 to i8*), align 1, !tbaa !1
    %and.i.i = and i8 %6, -3
    store volatile i8 %and.i.i, i8* inttoptr (i16 111 to i8*), align 1, !tbaa !1
    br label %_Z6noToneh.exit

    sw.bb.4.i.i: ; preds = %for.inc.i
    %7 = load volatile i8, i8* inttoptr (i16 112 to i8*), align 16, !tbaa !1
    %and6.i.i = and i8 %7, -3
    store volatile i8 %and6.i.i, i8* inttoptr (i16 112 to i8*), align 16, !tbaa !1
    store volatile i8 1, i8* inttoptr (i16 176 to i8*), align 16, !tbaa !1
    %8 = load volatile i8, i8* inttoptr (i16 177 to i8*), align 1, !tbaa !1
    %and9.i.i = and i8 %8, -8
    %or.i.i = or i8 %and9.i.i, 4
    store volatile i8 %or.i.i, i8* inttoptr (i16 177 to i8*), align 1, !tbaa !1
    store volatile i8 0, i8* inttoptr (i16 179 to i8*), align 1, !tbaa !1
    br label %_Z6noToneh.exit

    for.inc.i: ; preds = %entry
    %9 = load i8, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @_ZL9tone_pins, i16 0, i16 0), align 1, !tbaa !1
    %10 = tail call i8 asm sideeffect "lpm\0A\09mov $0, r0\0A\09", "=r,z,~{r0}"(i16 ptrtoint ([1 x i8]* @_ZL21tone_pin_to_timer_PGM to i16)) #3, !srcloc !21
    store i8 -1, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @_ZL9tone_pins, i16 0, i16 0), align 1, !tbaa !1
    switch i8 %10, label %_Z6noToneh.exit [
    i8 0, label %sw.bb.i.i
    i8 1, label %sw.bb.1.i.i
    i8 2, label %sw.bb.4.i.i
    ]

    _Z6noToneh.exit: ; preds = %sw.bb.i.i, %sw.bb.1.i.i, %sw.bb.4.i.i, %for.inc.i
    tail call void @digitalWrite(i8 zeroext %9, i8 zeroext 0)
    br label %if.end.5

    if.end.5: ; preds = %if.then, %if.then.4, %_Z6noToneh.exit
    ret void
    }

    attributes #0 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #1 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #2 = { noinline "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #3 = { nounwind }

    !llvm.ident = !{!0}

    !0 = !{!"clang version 3.7.0 (https://github.com/llvm-mirror/clang.git 287e62c84a1ccd74fbca46bfc13e364e314d4b41) (https://github.com/llvm-mirror/llvm.git d98a9c55e1add3cb93d7424a86828510d0557a2c)"}
    !1 = !{!2, !2, i64 0}
    !2 = !{!"omnipotent char", !3, i64 0}
    !3 = !{!"Simple C/C++ TBAA"}
    !4 = !{i32 -2147053691, i32 -2147053682, i32 -2147053641}
    !5 = !{i32 -2147053014, i32 -2147053005, i32 -2147052964}
    !6 = !{i32 -2147047230, i32 -2147047221, i32 -2147047180}
    !7 = !{i32 -2147047995, i32 -2147047976, i32 -2147047930, i32 -2147047884, i32 -2147047838, i32 -2147047792}
    !8 = !{!9, !9, i64 0}
    !9 = !{!"any pointer", !2, i64 0}
    !10 = !{i32 -2147046487, i32 -2147046478, i32 -2147046437}
    !11 = !{i32 -2147041224, i32 -2147041215, i32 -2147041174}
    !12 = !{i32 -2147041989, i32 -2147041970, i32 -2147041924, i32 -2147041878, i32 -2147041832, i32 -2147041786}
    !13 = !{i32 -2147040481, i32 -2147040472, i32 -2147040431}
    !14 = !{i32 -2147035218, i32 -2147035209, i32 -2147035168}
    !15 = !{i32 -2147035983, i32 -2147035964, i32 -2147035918, i32 -2147035872, i32 -2147035826, i32 -2147035780}
    !16 = !{i32 -2147034475, i32 -2147034466, i32 -2147034425}
    !17 = !{!18, !18, i64 0}
    !18 = !{!"long", !2, i64 0}
    !19 = !{!20, !20, i64 0}
    !20 = !{!"short", !2, i64 0}
    !21 = !{i32 -2147030741, i32 -2147030732, i32 -2147030691}
    130 changes: 129 additions & 1 deletion WInterrupts.ll
    Original file line number Diff line number Diff line change
    @@ -1 +1,129 @@
    this file failed compilation with clang
    ; ModuleID = 'WInterrupts.c'
    target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-i64:8:8-f32:8:8-f64:8:8-n8"
    target triple = "avr"

    @intFunc = internal global [2 x void ()*] zeroinitializer, align 2
    @llvm.used = appending global [2 x i8*] [i8* bitcast (void ()* @__vector_1 to i8*), i8* bitcast (void ()* @__vector_2 to i8*)], section "llvm.metadata"

    ; Function Attrs: nounwind
    define void @attachInterrupt(i8 zeroext %interruptNum, void ()* %userFunc, i16 %mode) #0 {
    entry:
    %cmp = icmp ult i8 %interruptNum, 2
    br i1 %cmp, label %if.then, label %if.end

    if.then: ; preds = %entry
    %conv = zext i8 %interruptNum to i16
    %arrayidx = getelementptr inbounds [2 x void ()*], [2 x void ()*]* @intFunc, i16 0, i16 %conv
    store volatile void ()* %userFunc, void ()** %arrayidx, align 2, !tbaa !1
    switch i8 %interruptNum, label %if.end [
    i8 0, label %sw.bb
    i8 1, label %sw.bb.8
    ]

    sw.bb: ; preds = %if.then
    %0 = load volatile i8, i8* inttoptr (i16 105 to i8*), align 1, !tbaa !5
    %conv3 = zext i8 %0 to i16
    %and = and i16 %conv3, 252
    %or = or i16 %and, %mode
    %conv4 = trunc i16 %or to i8
    store volatile i8 %conv4, i8* inttoptr (i16 105 to i8*), align 1, !tbaa !5
    %1 = load volatile i8, i8* inttoptr (i16 61 to i8*), align 1, !tbaa !5
    %or6 = or i8 %1, 1
    store volatile i8 %or6, i8* inttoptr (i16 61 to i8*), align 1, !tbaa !5
    br label %if.end

    sw.bb.8: ; preds = %if.then
    %2 = load volatile i8, i8* inttoptr (i16 105 to i8*), align 1, !tbaa !5
    %conv9 = zext i8 %2 to i16
    %and10 = and i16 %conv9, 243
    %shl11 = shl i16 %mode, 2
    %or12 = or i16 %and10, %shl11
    %conv13 = trunc i16 %or12 to i8
    store volatile i8 %conv13, i8* inttoptr (i16 105 to i8*), align 1, !tbaa !5
    %3 = load volatile i8, i8* inttoptr (i16 61 to i8*), align 1, !tbaa !5
    %or15 = or i8 %3, 2
    store volatile i8 %or15, i8* inttoptr (i16 61 to i8*), align 1, !tbaa !5
    br label %if.end

    if.end: ; preds = %sw.bb, %sw.bb.8, %if.then, %entry
    ret void
    }

    ; Function Attrs: nounwind
    define void @detachInterrupt(i8 zeroext %interruptNum) #0 {
    entry:
    %conv = zext i8 %interruptNum to i16
    %cmp = icmp ult i8 %interruptNum, 2
    br i1 %cmp, label %if.then, label %if.end

    if.then: ; preds = %entry
    switch i8 %interruptNum, label %sw.epilog [
    i8 0, label %sw.bb
    i8 1, label %sw.bb.5
    ]

    sw.bb: ; preds = %if.then
    %0 = load volatile i8, i8* inttoptr (i16 61 to i8*), align 1, !tbaa !5
    %and = and i8 %0, -2
    store volatile i8 %and, i8* inttoptr (i16 61 to i8*), align 1, !tbaa !5
    br label %sw.epilog

    sw.bb.5: ; preds = %if.then
    %1 = load volatile i8, i8* inttoptr (i16 61 to i8*), align 1, !tbaa !5
    %and7 = and i8 %1, -3
    store volatile i8 %and7, i8* inttoptr (i16 61 to i8*), align 1, !tbaa !5
    br label %sw.epilog

    sw.epilog: ; preds = %if.then, %sw.bb.5, %sw.bb
    %arrayidx = getelementptr inbounds [2 x void ()*], [2 x void ()*]* @intFunc, i16 0, i16 %conv
    store volatile void ()* null, void ()** %arrayidx, align 2, !tbaa !1
    br label %if.end

    if.end: ; preds = %sw.epilog, %entry
    ret void
    }

    ; Function Attrs: noinline nounwind
    define avr_signalcc void @__vector_1() #1 {
    entry:
    %0 = load volatile void ()*, void ()** getelementptr inbounds ([2 x void ()*], [2 x void ()*]* @intFunc, i16 0, i16 0), align 2, !tbaa !1
    %tobool = icmp eq void ()* %0, null
    br i1 %tobool, label %if.end, label %if.then

    if.then: ; preds = %entry
    %1 = load volatile void ()*, void ()** getelementptr inbounds ([2 x void ()*], [2 x void ()*]* @intFunc, i16 0, i16 0), align 2, !tbaa !1
    tail call void %1() #2
    br label %if.end

    if.end: ; preds = %entry, %if.then
    ret void
    }

    ; Function Attrs: noinline nounwind
    define avr_signalcc void @__vector_2() #1 {
    entry:
    %0 = load volatile void ()*, void ()** getelementptr inbounds ([2 x void ()*], [2 x void ()*]* @intFunc, i16 0, i16 1), align 2, !tbaa !1
    %tobool = icmp eq void ()* %0, null
    br i1 %tobool, label %if.end, label %if.then

    if.then: ; preds = %entry
    %1 = load volatile void ()*, void ()** getelementptr inbounds ([2 x void ()*], [2 x void ()*]* @intFunc, i16 0, i16 1), align 2, !tbaa !1
    tail call void %1() #2
    br label %if.end

    if.end: ; preds = %entry, %if.then
    ret void
    }

    attributes #0 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #1 = { noinline nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #2 = { nounwind }

    !llvm.ident = !{!0}

    !0 = !{!"clang version 3.7.0 (https://github.com/llvm-mirror/clang.git 287e62c84a1ccd74fbca46bfc13e364e314d4b41) (https://github.com/llvm-mirror/llvm.git d98a9c55e1add3cb93d7424a86828510d0557a2c)"}
    !1 = !{!2, !2, i64 0}
    !2 = !{!"any pointer", !3, i64 0}
    !3 = !{!"omnipotent char", !4, i64 0}
    !4 = !{!"Simple C/C++ TBAA"}
    !5 = !{!3, !3, i64 0}
    221 changes: 220 additions & 1 deletion wiring.ll
    Original file line number Diff line number Diff line change
    @@ -1 +1,220 @@
    this file failed compilation with clang
    ; ModuleID = 'wiring.c'
    target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-i64:8:8-f32:8:8-f64:8:8-n8"
    target triple = "avr"

    @timer0_overflow_count = global i32 0, align 2
    @timer0_millis = global i32 0, align 2
    @timer0_fract = internal unnamed_addr global i8 0, align 1
    @llvm.used = appending global [1 x i8*] [i8* bitcast (void ()* @__vector_16 to i8*)], section "llvm.metadata"

    ; Function Attrs: noinline nounwind
    define avr_signalcc void @__vector_16() #0 {
    entry:
    %0 = load volatile i32, i32* @timer0_millis, align 2, !tbaa !1
    %1 = load i8, i8* @timer0_fract, align 1, !tbaa !5
    %add1 = add i8 %1, 3
    %cmp = icmp ugt i8 %add1, 124
    %sub = add i8 %1, -122
    %m.0.v = select i1 %cmp, i32 2, i32 1
    %m.0 = add i32 %m.0.v, %0
    %f.0 = select i1 %cmp, i8 %sub, i8 %add1
    store i8 %f.0, i8* @timer0_fract, align 1, !tbaa !5
    store volatile i32 %m.0, i32* @timer0_millis, align 2, !tbaa !1
    %2 = load volatile i32, i32* @timer0_overflow_count, align 2, !tbaa !1
    %inc = add i32 %2, 1
    store volatile i32 %inc, i32* @timer0_overflow_count, align 2, !tbaa !1
    ret void
    }

    ; Function Attrs: nounwind
    define i32 @millis() #1 {
    entry:
    %0 = load volatile i8, i8* inttoptr (i16 95 to i8*), align 1, !tbaa !5
    tail call void asm sideeffect "cli", "~{memory}"() #3, !srcloc !6
    %1 = load volatile i32, i32* @timer0_millis, align 2, !tbaa !1
    store volatile i8 %0, i8* inttoptr (i16 95 to i8*), align 1, !tbaa !5
    ret i32 %1
    }

    ; Function Attrs: nounwind
    define i32 @micros() #1 {
    entry:
    %0 = load volatile i8, i8* inttoptr (i16 95 to i8*), align 1, !tbaa !5
    tail call void asm sideeffect "cli", "~{memory}"() #3, !srcloc !7
    %1 = load volatile i32, i32* @timer0_overflow_count, align 2, !tbaa !1
    %2 = load volatile i8, i8* inttoptr (i16 70 to i8*), align 2, !tbaa !5
    %3 = load volatile i8, i8* inttoptr (i16 53 to i8*), align 1, !tbaa !5
    %and = and i8 %3, 1
    %cmp = icmp eq i8 %2, -1
    %4 = xor i8 %and, 1
    %tobool7 = zext i8 %4 to i32
    %cmp8 = zext i1 %cmp to i32
    %5 = or i32 %tobool7, %cmp8
    %inc = xor i32 %5, 1
    %m.0 = add i32 %inc, %1
    store volatile i8 %0, i8* inttoptr (i16 95 to i8*), align 1, !tbaa !5
    %shl = shl i32 %m.0, 8
    %conv3 = zext i8 %2 to i32
    %add = or i32 %shl, %conv3
    %mul = shl i32 %add, 2
    ret i32 %mul
    }

    ; Function Attrs: nounwind
    define void @delay(i32 %ms) #1 {
    entry:
    %0 = load volatile i8, i8* inttoptr (i16 95 to i8*), align 1, !tbaa !5
    tail call void asm sideeffect "cli", "~{memory}"() #3, !srcloc !7
    %1 = load volatile i32, i32* @timer0_overflow_count, align 2, !tbaa !1
    %2 = load volatile i8, i8* inttoptr (i16 70 to i8*), align 2, !tbaa !5
    %3 = load volatile i8, i8* inttoptr (i16 53 to i8*), align 1, !tbaa !5
    store volatile i8 %0, i8* inttoptr (i16 95 to i8*), align 1, !tbaa !5
    %cmp.19 = icmp eq i32 %ms, 0
    br i1 %cmp.19, label %while.end.split, label %while.cond.outer.while.cond.outer.split_crit_edge.lr.ph

    while.cond.outer.while.cond.outer.split_crit_edge.lr.ph: ; preds = %entry
    %and.i = and i8 %3, 1
    %4 = xor i8 %and.i, 1
    %tobool7.i = zext i8 %4 to i32
    %cmp.i = icmp eq i8 %2, -1
    %cmp8.i = zext i1 %cmp.i to i32
    %5 = or i32 %tobool7.i, %cmp8.i
    %inc.i = xor i32 %5, 1
    %m.0.i = add i32 %inc.i, %1
    %shl.i = shl i32 %m.0.i, 8
    %conv3.i = zext i8 %2 to i32
    %add.i = or i32 %shl.i, %conv3.i
    %mul.i = shl i32 %add.i, 2
    %conv = trunc i32 %mul.i to i16
    br label %while.cond.outer.while.cond.outer.split_crit_edge

    while.cond.outer.while.cond.outer.split_crit_edge: ; preds = %while.cond.outer.while.cond.outer.split_crit_edge.lr.ph, %if.then
    %start.0.ph21 = phi i16 [ %conv, %while.cond.outer.while.cond.outer.split_crit_edge.lr.ph ], [ %add, %if.then ]
    %ms.addr.0.ph20 = phi i32 [ %ms, %while.cond.outer.while.cond.outer.split_crit_edge.lr.ph ], [ %dec, %if.then ]
    br label %while.body

    while.body: ; preds = %while.body, %while.cond.outer.while.cond.outer.split_crit_edge
    tail call void @yield() #3
    %6 = load volatile i8, i8* inttoptr (i16 95 to i8*), align 1, !tbaa !5
    tail call void asm sideeffect "cli", "~{memory}"() #3, !srcloc !7
    %7 = load volatile i32, i32* @timer0_overflow_count, align 2, !tbaa !1
    %8 = load volatile i8, i8* inttoptr (i16 70 to i8*), align 2, !tbaa !5
    %9 = load volatile i8, i8* inttoptr (i16 53 to i8*), align 1, !tbaa !5
    %and.i.9 = and i8 %9, 1
    %cmp.i.10 = icmp eq i8 %8, -1
    %10 = xor i8 %and.i.9, 1
    %tobool7.i.11 = zext i8 %10 to i32
    %cmp8.i.12 = zext i1 %cmp.i.10 to i32
    %11 = or i32 %tobool7.i.11, %cmp8.i.12
    %inc.i.13 = xor i32 %11, 1
    %m.0.i.14 = add i32 %inc.i.13, %7
    store volatile i8 %6, i8* inttoptr (i16 95 to i8*), align 1, !tbaa !5
    %shl.i.15 = shl i32 %m.0.i.14, 8
    %conv3.i.16 = zext i8 %8 to i32
    %add.i.17 = or i32 %shl.i.15, %conv3.i.16
    %mul.i.18 = shl i32 %add.i.17, 2
    %conv3 = trunc i32 %mul.i.18 to i16
    %sub = sub i16 %conv3, %start.0.ph21
    %cmp4 = icmp ugt i16 %sub, 999
    br i1 %cmp4, label %if.then, label %while.body

    if.then: ; preds = %while.body
    %dec = add i32 %ms.addr.0.ph20, -1
    %add = add i16 %start.0.ph21, 1000
    %cmp = icmp eq i32 %dec, 0
    br i1 %cmp, label %while.end.split.loopexit, label %while.cond.outer.while.cond.outer.split_crit_edge

    while.end.split.loopexit: ; preds = %if.then
    br label %while.end.split

    while.end.split: ; preds = %while.end.split.loopexit, %entry
    ret void
    }

    declare void @yield() #2

    ; Function Attrs: nounwind
    define void @delayMicroseconds(i16 %us) #1 {
    entry:
    %dec = add i16 %us, -1
    %cmp = icmp eq i16 %dec, 0
    br i1 %cmp, label %return, label %if.end

    if.end: ; preds = %entry
    %shl = shl i16 %dec, 2
    %sub = add i16 %shl, -2
    %0 = tail call i16 asm sideeffect "1: sbiw $0,1\0A\09brne 1b", "=w,0"(i16 %sub) #3, !srcloc !8
    br label %return

    return: ; preds = %entry, %if.end
    ret void
    }

    ; Function Attrs: nounwind
    define void @init() #1 {
    entry:
    tail call void asm sideeffect "sei", "~{memory}"() #3, !srcloc !9
    %0 = load volatile i8, i8* inttoptr (i16 68 to i8*), align 4, !tbaa !5
    %or = or i8 %0, 2
    store volatile i8 %or, i8* inttoptr (i16 68 to i8*), align 4, !tbaa !5
    %1 = load volatile i8, i8* inttoptr (i16 68 to i8*), align 4, !tbaa !5
    %or3 = or i8 %1, 1
    store volatile i8 %or3, i8* inttoptr (i16 68 to i8*), align 4, !tbaa !5
    %2 = load volatile i8, i8* inttoptr (i16 69 to i8*), align 1, !tbaa !5
    %or6 = or i8 %2, 2
    store volatile i8 %or6, i8* inttoptr (i16 69 to i8*), align 1, !tbaa !5
    %3 = load volatile i8, i8* inttoptr (i16 69 to i8*), align 1, !tbaa !5
    %or9 = or i8 %3, 1
    store volatile i8 %or9, i8* inttoptr (i16 69 to i8*), align 1, !tbaa !5
    %4 = load volatile i8, i8* inttoptr (i16 110 to i8*), align 2, !tbaa !5
    %or12 = or i8 %4, 1
    store volatile i8 %or12, i8* inttoptr (i16 110 to i8*), align 2, !tbaa !5
    store volatile i8 0, i8* inttoptr (i16 129 to i8*), align 1, !tbaa !5
    %5 = load volatile i8, i8* inttoptr (i16 129 to i8*), align 1, !tbaa !5
    %or15 = or i8 %5, 2
    store volatile i8 %or15, i8* inttoptr (i16 129 to i8*), align 1, !tbaa !5
    %6 = load volatile i8, i8* inttoptr (i16 129 to i8*), align 1, !tbaa !5
    %or18 = or i8 %6, 1
    store volatile i8 %or18, i8* inttoptr (i16 129 to i8*), align 1, !tbaa !5
    %7 = load volatile i8, i8* inttoptr (i16 128 to i8*), align 128, !tbaa !5
    %or21 = or i8 %7, 1
    store volatile i8 %or21, i8* inttoptr (i16 128 to i8*), align 128, !tbaa !5
    %8 = load volatile i8, i8* inttoptr (i16 177 to i8*), align 1, !tbaa !5
    %or24 = or i8 %8, 4
    store volatile i8 %or24, i8* inttoptr (i16 177 to i8*), align 1, !tbaa !5
    %9 = load volatile i8, i8* inttoptr (i16 176 to i8*), align 16, !tbaa !5
    %or27 = or i8 %9, 1
    store volatile i8 %or27, i8* inttoptr (i16 176 to i8*), align 16, !tbaa !5
    %10 = load volatile i8, i8* inttoptr (i16 122 to i8*), align 2, !tbaa !5
    %or30 = or i8 %10, 4
    store volatile i8 %or30, i8* inttoptr (i16 122 to i8*), align 2, !tbaa !5
    %11 = load volatile i8, i8* inttoptr (i16 122 to i8*), align 2, !tbaa !5
    %or33 = or i8 %11, 2
    store volatile i8 %or33, i8* inttoptr (i16 122 to i8*), align 2, !tbaa !5
    %12 = load volatile i8, i8* inttoptr (i16 122 to i8*), align 2, !tbaa !5
    %or36 = or i8 %12, 1
    store volatile i8 %or36, i8* inttoptr (i16 122 to i8*), align 2, !tbaa !5
    %13 = load volatile i8, i8* inttoptr (i16 122 to i8*), align 2, !tbaa !5
    %or39 = or i8 %13, -128
    store volatile i8 %or39, i8* inttoptr (i16 122 to i8*), align 2, !tbaa !5
    store volatile i8 0, i8* inttoptr (i16 193 to i8*), align 1, !tbaa !5
    ret void
    }

    attributes #0 = { noinline nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #1 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #2 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #3 = { nounwind }

    !llvm.ident = !{!0}

    !0 = !{!"clang version 3.7.0 (https://github.com/llvm-mirror/clang.git 287e62c84a1ccd74fbca46bfc13e364e314d4b41) (https://github.com/llvm-mirror/llvm.git d98a9c55e1add3cb93d7424a86828510d0557a2c)"}
    !1 = !{!2, !2, i64 0}
    !2 = !{!"long", !3, i64 0}
    !3 = !{!"omnipotent char", !4, i64 0}
    !4 = !{!"Simple C/C++ TBAA"}
    !5 = !{!3, !3, i64 0}
    !6 = !{i32 -2147149207}
    !7 = !{i32 -2147148893}
    !8 = !{i32 5039, i32 5057}
    !9 = !{i32 -2147148378}
  2. Dylan McKay revised this gist Jul 8, 2015. 4 changed files with 4 additions and 0 deletions.
    1 change: 1 addition & 0 deletions HardwareSerial0.ll
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    this file failed compilation with clang
    1 change: 1 addition & 0 deletions Tone.ll
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    this file failed compilation with clang
    1 change: 1 addition & 0 deletions WInterrupts.ll
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    this file failed compilation with clang
    1 change: 1 addition & 0 deletions wiring.ll
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    this file failed compilation with clang
  3. Dylan McKay renamed this gist Jul 8, 2015. 1 changed file with 0 additions and 0 deletions.
  4. Dylan McKay renamed this gist Jul 8, 2015. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  5. Dylan McKay renamed this gist Jul 8, 2015. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  6. Dylan McKay renamed this gist Jul 8, 2015. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  7. Dylan McKay renamed this gist Jul 8, 2015. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  8. Dylan McKay revised this gist Jul 8, 2015. 20 changed files with 7164 additions and 0 deletions.
    7 changes: 7 additions & 0 deletions CDC.ll
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,7 @@
    ; ModuleID = './CDC.cpp'
    target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-i64:8:8-f32:8:8-f64:8:8-n8"
    target triple = "avr"

    !llvm.ident = !{!0}

    !0 = !{!"clang version 3.7.0 (https://github.com/llvm-mirror/clang.git 287e62c84a1ccd74fbca46bfc13e364e314d4b41) (https://github.com/llvm-mirror/llvm.git aaab572fc38b4438e769e2fd6b91963be11db7b2)"}
    7 changes: 7 additions & 0 deletions HID.ll
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,7 @@
    ; ModuleID = './HID.cpp'
    target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-i64:8:8-f32:8:8-f64:8:8-n8"
    target triple = "avr"

    !llvm.ident = !{!0}

    !0 = !{!"clang version 3.7.0 (https://github.com/llvm-mirror/clang.git 287e62c84a1ccd74fbca46bfc13e364e314d4b41) (https://github.com/llvm-mirror/llvm.git aaab572fc38b4438e769e2fd6b91963be11db7b2)"}
    483 changes: 483 additions & 0 deletions HardwareSerial.ll
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,483 @@
    ; ModuleID = './HardwareSerial.cpp'
    target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-i64:8:8-f32:8:8-f64:8:8-n8"
    target triple = "avr"

    %class.HardwareSerial = type { %class.Stream, i8*, i8*, i8*, i8*, i8*, i8*, i8, i8, i8, i8, i8, [64 x i8], [64 x i8], i8 }
    %class.Stream = type { %class.Print, i32, i32 }
    %class.Print = type { i32 (...)**, i16 }

    $_ZTS6Stream = comdat any

    $_ZTI6Stream = comdat any

    @_ZTV14HardwareSerial = unnamed_addr constant [8 x i8*] [i8* null, i8* bitcast ({ i8*, i8*, i8* }* @_ZTI14HardwareSerial to i8*), i8* bitcast (i16 (%class.HardwareSerial*, i8)* @_ZN14HardwareSerial5writeEh to i8*), i8* bitcast (i16 (%class.Print*, i8*, i16)* @_ZN5Print5writeEPKhj to i8*), i8* bitcast (i16 (%class.HardwareSerial*)* @_ZN14HardwareSerial9availableEv to i8*), i8* bitcast (i16 (%class.HardwareSerial*)* @_ZN14HardwareSerial4readEv to i8*), i8* bitcast (i16 (%class.HardwareSerial*)* @_ZN14HardwareSerial4peekEv to i8*), i8* bitcast (void (%class.HardwareSerial*)* @_ZN14HardwareSerial5flushEv to i8*)], align 2
    @_ZTVN10__cxxabiv120__si_class_type_infoE = external global i8*
    @_ZTS14HardwareSerial = constant [17 x i8] c"14HardwareSerial\00"
    @_ZTS6Stream = linkonce_odr constant [8 x i8] c"6Stream\00", comdat
    @_ZTI5Print = external constant i8*
    @_ZTI6Stream = linkonce_odr constant { i8*, i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv120__si_class_type_infoE, i16 2) to i8*), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @_ZTS6Stream, i32 0, i32 0), i8* bitcast (i8** @_ZTI5Print to i8*) }, comdat
    @_ZTI14HardwareSerial = constant { i8*, i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv120__si_class_type_infoE, i16 2) to i8*), i8* getelementptr inbounds ([17 x i8], [17 x i8]* @_ZTS14HardwareSerial, i32 0, i32 0), i8* bitcast ({ i8*, i8*, i8* }* @_ZTI6Stream to i8*) }

    define weak void @_Z14serialEventRunv() #0 {
    entry:
    br i1 or (i1 icmp eq (i1 ()* @_Z17Serial0_availablev, i1 ()* null), i1 icmp eq (void ()* @_Z11serialEventv, void ()* null)), label %if.end, label %land.lhs.true.1

    land.lhs.true.1: ; preds = %entry
    %call = tail call zeroext i1 @_Z17Serial0_availablev()
    br i1 %call, label %if.then, label %if.end

    if.then: ; preds = %land.lhs.true.1
    tail call void @_Z11serialEventv()
    br label %if.end

    if.end: ; preds = %entry, %if.then, %land.lhs.true.1
    ret void
    }

    declare extern_weak zeroext i1 @_Z17Serial0_availablev() #0

    declare extern_weak void @_Z11serialEventv() #0

    ; Function Attrs: nounwind
    define void @_ZN14HardwareSerial17_tx_udr_empty_irqEv(%class.HardwareSerial* nocapture %this) #1 align 2 {
    entry:
    %_tx_buffer_tail = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 11
    %0 = load volatile i8, i8* %_tx_buffer_tail, align 1, !tbaa !1
    %idxprom = zext i8 %0 to i16
    %arrayidx = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 13, i16 %idxprom
    %1 = load i8, i8* %arrayidx, align 1, !tbaa !7
    %2 = load volatile i8, i8* %_tx_buffer_tail, align 1, !tbaa !1
    %add = add i8 %2, 1
    %rem = and i8 %add, 63
    store volatile i8 %rem, i8* %_tx_buffer_tail, align 1, !tbaa !1
    %_udr = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 6
    %3 = load i8*, i8** %_udr, align 2, !tbaa !8
    store volatile i8 %1, i8* %3, align 1, !tbaa !7
    %_ucsra = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 3
    %4 = load i8*, i8** %_ucsra, align 2, !tbaa !9
    %5 = load volatile i8, i8* %4, align 1, !tbaa !7
    %or = or i8 %5, 64
    store volatile i8 %or, i8* %4, align 1, !tbaa !7
    %_tx_buffer_head = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 10
    %6 = load volatile i8, i8* %_tx_buffer_head, align 1, !tbaa !10
    %7 = load volatile i8, i8* %_tx_buffer_tail, align 1, !tbaa !1
    %cmp = icmp eq i8 %6, %7
    br i1 %cmp, label %if.then, label %if.end

    if.then: ; preds = %entry
    %_ucsrb = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 4
    %8 = load i8*, i8** %_ucsrb, align 2, !tbaa !11
    %9 = load volatile i8, i8* %8, align 1, !tbaa !7
    %and = and i8 %9, -33
    store volatile i8 %and, i8* %8, align 1, !tbaa !7
    br label %if.end

    if.end: ; preds = %if.then, %entry
    ret void
    }

    ; Function Attrs: nounwind
    define void @_ZN14HardwareSerial5beginEmh(%class.HardwareSerial* nocapture %this, i32 %baud, i8 zeroext %config) #1 align 2 {
    entry:
    %div = udiv i32 4000000, %baud
    %sub = add nuw nsw i32 %div, 131071
    %div2 = lshr i32 %sub, 1
    %conv = trunc i32 %div2 to i16
    %_ucsra = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 3
    %0 = load i8*, i8** %_ucsra, align 2, !tbaa !9
    store volatile i8 2, i8* %0, align 1, !tbaa !7
    %cmp = icmp eq i32 %baud, 57600
    %cmp3 = icmp ugt i16 %conv, 4095
    %or.cond = or i1 %cmp, %cmp3
    %extract.t29 = trunc i32 %div2 to i8
    %extract3133 = lshr i32 %sub, 9
    %extract.t32 = trunc i32 %extract3133 to i8
    br i1 %or.cond, label %if.then, label %if.end

    if.then: ; preds = %entry
    %1 = load i8*, i8** %_ucsra, align 2, !tbaa !9
    store volatile i8 0, i8* %1, align 1, !tbaa !7
    %div5 = udiv i32 2000000, %baud
    %sub6 = add nsw i32 %div5, -1
    %div7 = lshr i32 %sub6, 1
    %extract.t = trunc i32 %div7 to i8
    %extract35 = lshr i32 %sub6, 9
    %extract.t30 = trunc i32 %extract35 to i8
    br label %if.end

    if.end: ; preds = %entry, %if.then
    %baud_setting.0.off0 = phi i8 [ %extract.t, %if.then ], [ %extract.t29, %entry ]
    %baud_setting.0.off8 = phi i8 [ %extract.t30, %if.then ], [ %extract.t32, %entry ]
    %_ubrrh = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 1
    %2 = load i8*, i8** %_ubrrh, align 2, !tbaa !12
    store volatile i8 %baud_setting.0.off8, i8* %2, align 1, !tbaa !7
    %_ubrrl = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 2
    %3 = load i8*, i8** %_ubrrl, align 2, !tbaa !13
    store volatile i8 %baud_setting.0.off0, i8* %3, align 1, !tbaa !7
    %_written = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 7
    store i8 0, i8* %_written, align 1, !tbaa !14
    %_ucsrc = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 5
    %4 = load i8*, i8** %_ucsrc, align 2, !tbaa !15
    store volatile i8 %config, i8* %4, align 1, !tbaa !7
    %_ucsrb = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 4
    %5 = load i8*, i8** %_ucsrb, align 2, !tbaa !11
    %6 = load volatile i8, i8* %5, align 1, !tbaa !7
    %or = or i8 %6, 16
    store volatile i8 %or, i8* %5, align 1, !tbaa !7
    %7 = load i8*, i8** %_ucsrb, align 2, !tbaa !11
    %8 = load volatile i8, i8* %7, align 1, !tbaa !7
    %or15 = or i8 %8, 8
    store volatile i8 %or15, i8* %7, align 1, !tbaa !7
    %9 = load i8*, i8** %_ucsrb, align 2, !tbaa !11
    %10 = load volatile i8, i8* %9, align 1, !tbaa !7
    %or19 = or i8 %10, -128
    store volatile i8 %or19, i8* %9, align 1, !tbaa !7
    %11 = load i8*, i8** %_ucsrb, align 2, !tbaa !11
    %12 = load volatile i8, i8* %11, align 1, !tbaa !7
    %and = and i8 %12, -33
    store volatile i8 %and, i8* %11, align 1, !tbaa !7
    ret void
    }

    ; Function Attrs: nounwind
    define void @_ZN14HardwareSerial3endEv(%class.HardwareSerial* nocapture %this) #1 align 2 {
    entry:
    %_tx_buffer_head = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 10
    %_tx_buffer_tail = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 11
    br label %while.cond

    while.cond: ; preds = %while.cond, %entry
    %0 = load volatile i8, i8* %_tx_buffer_head, align 1, !tbaa !10
    %1 = load volatile i8, i8* %_tx_buffer_tail, align 1, !tbaa !1
    %cmp = icmp eq i8 %0, %1
    br i1 %cmp, label %while.end, label %while.cond

    while.end: ; preds = %while.cond
    %_ucsrb = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 4
    %2 = load i8*, i8** %_ucsrb, align 2, !tbaa !11
    %3 = load volatile i8, i8* %2, align 1, !tbaa !7
    %and = and i8 %3, -17
    store volatile i8 %and, i8* %2, align 1, !tbaa !7
    %4 = load i8*, i8** %_ucsrb, align 2, !tbaa !11
    %5 = load volatile i8, i8* %4, align 1, !tbaa !7
    %and7 = and i8 %5, -9
    store volatile i8 %and7, i8* %4, align 1, !tbaa !7
    %6 = load i8*, i8** %_ucsrb, align 2, !tbaa !11
    %7 = load volatile i8, i8* %6, align 1, !tbaa !7
    %and11 = and i8 %7, 127
    store volatile i8 %and11, i8* %6, align 1, !tbaa !7
    %8 = load i8*, i8** %_ucsrb, align 2, !tbaa !11
    %9 = load volatile i8, i8* %8, align 1, !tbaa !7
    %and15 = and i8 %9, -33
    store volatile i8 %and15, i8* %8, align 1, !tbaa !7
    %_rx_buffer_tail = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 9
    %10 = load volatile i8, i8* %_rx_buffer_tail, align 1, !tbaa !16
    %_rx_buffer_head = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 8
    store volatile i8 %10, i8* %_rx_buffer_head, align 1, !tbaa !17
    ret void
    }

    ; Function Attrs: nounwind
    define i16 @_ZN14HardwareSerial9availableEv(%class.HardwareSerial* nocapture readonly %this) unnamed_addr #1 align 2 {
    entry:
    %_rx_buffer_head = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 8
    %0 = load volatile i8, i8* %_rx_buffer_head, align 1, !tbaa !17
    %conv = zext i8 %0 to i16
    %_rx_buffer_tail = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 9
    %1 = load volatile i8, i8* %_rx_buffer_tail, align 1, !tbaa !16
    %conv2 = zext i8 %1 to i16
    %sub = sub nsw i16 %conv, %conv2
    %rem = and i16 %sub, 63
    ret i16 %rem
    }

    ; Function Attrs: nounwind
    define i16 @_ZN14HardwareSerial4peekEv(%class.HardwareSerial* nocapture readonly %this) unnamed_addr #1 align 2 {
    entry:
    %_rx_buffer_head = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 8
    %0 = load volatile i8, i8* %_rx_buffer_head, align 1, !tbaa !17
    %_rx_buffer_tail = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 9
    %1 = load volatile i8, i8* %_rx_buffer_tail, align 1, !tbaa !16
    %cmp = icmp eq i8 %0, %1
    br i1 %cmp, label %return, label %if.else

    if.else: ; preds = %entry
    %2 = load volatile i8, i8* %_rx_buffer_tail, align 1, !tbaa !16
    %idxprom = zext i8 %2 to i16
    %arrayidx = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 12, i16 %idxprom
    %3 = load i8, i8* %arrayidx, align 1, !tbaa !7
    %conv4 = zext i8 %3 to i16
    br label %return

    return: ; preds = %entry, %if.else
    %retval.0 = phi i16 [ %conv4, %if.else ], [ -1, %entry ]
    ret i16 %retval.0
    }

    ; Function Attrs: nounwind
    define i16 @_ZN14HardwareSerial4readEv(%class.HardwareSerial* nocapture %this) unnamed_addr #1 align 2 {
    entry:
    %_rx_buffer_head = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 8
    %0 = load volatile i8, i8* %_rx_buffer_head, align 1, !tbaa !17
    %_rx_buffer_tail = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 9
    %1 = load volatile i8, i8* %_rx_buffer_tail, align 1, !tbaa !16
    %cmp = icmp eq i8 %0, %1
    br i1 %cmp, label %return, label %if.else

    if.else: ; preds = %entry
    %2 = load volatile i8, i8* %_rx_buffer_tail, align 1, !tbaa !16
    %idxprom = zext i8 %2 to i16
    %arrayidx = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 12, i16 %idxprom
    %3 = load i8, i8* %arrayidx, align 1, !tbaa !7
    %4 = load volatile i8, i8* %_rx_buffer_tail, align 1, !tbaa !16
    %add = add i8 %4, 1
    %5 = and i8 %add, 63
    store volatile i8 %5, i8* %_rx_buffer_tail, align 1, !tbaa !16
    %conv10 = zext i8 %3 to i16
    br label %return

    return: ; preds = %entry, %if.else
    %retval.0 = phi i16 [ %conv10, %if.else ], [ -1, %entry ]
    ret i16 %retval.0
    }

    ; Function Attrs: nounwind
    define i16 @_ZN14HardwareSerial17availableForWriteEv(%class.HardwareSerial* nocapture readonly %this) #1 align 2 {
    entry:
    %_tx_buffer_head = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 10
    %0 = load volatile i8, i8* %_tx_buffer_head, align 1, !tbaa !10
    %_tx_buffer_tail = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 11
    %1 = load volatile i8, i8* %_tx_buffer_tail, align 1, !tbaa !1
    %conv = zext i8 %0 to i16
    %conv2 = zext i8 %1 to i16
    %cmp = icmp ugt i8 %1, %0
    %sub = sub nsw i16 63, %conv
    %sub7 = xor i16 %conv, -1
    %retval.0.v = select i1 %cmp, i16 %sub7, i16 %sub
    %retval.0 = add nsw i16 %conv2, %retval.0.v
    ret i16 %retval.0
    }

    ; Function Attrs: nounwind
    define void @_ZN14HardwareSerial5flushEv(%class.HardwareSerial* nocapture %this) unnamed_addr #1 align 2 {
    entry:
    %_written = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 7
    %0 = load i8, i8* %_written, align 1, !tbaa !14, !range !18
    %tobool = icmp eq i8 %0, 0
    br i1 %tobool, label %while.end, label %while.cond.preheader

    while.cond.preheader: ; preds = %entry
    %_ucsra = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 3
    %_ucsrb = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 4
    %_tx_buffer_tail.i = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 11
    %_udr.i = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 6
    %_tx_buffer_head.i = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 10
    br label %while.cond

    while.cond: ; preds = %while.cond.backedge, %while.cond.preheader
    %1 = load i8*, i8** %_ucsrb, align 2, !tbaa !11
    %2 = load volatile i8, i8* %1, align 1, !tbaa !7
    %and = and i8 %2, 32
    %tobool2 = icmp eq i8 %and, 0
    br i1 %tobool2, label %lor.rhs, label %while.body

    lor.rhs: ; preds = %while.cond
    %3 = load i8*, i8** %_ucsra, align 2, !tbaa !9
    %4 = load volatile i8, i8* %3, align 1, !tbaa !7
    %and4 = and i8 %4, 64
    %lnot = icmp eq i8 %and4, 0
    br i1 %lnot, label %while.body, label %while.end.loopexit

    while.body: ; preds = %while.cond, %lor.rhs
    %5 = load volatile i8, i8* inttoptr (i16 95 to i8*), align 1, !tbaa !7
    %tobool8 = icmp slt i8 %5, 0
    br i1 %tobool8, label %while.cond.backedge, label %land.lhs.true

    while.cond.backedge: ; preds = %while.body, %land.lhs.true, %if.then.13, %if.then.18, %if.then.i
    br label %while.cond

    land.lhs.true: ; preds = %while.body
    %6 = load volatile i8, i8* %1, align 1, !tbaa !7
    %and11 = and i8 %6, 32
    %tobool12 = icmp eq i8 %and11, 0
    br i1 %tobool12, label %while.cond.backedge, label %if.then.13

    if.then.13: ; preds = %land.lhs.true
    %7 = load i8*, i8** %_ucsra, align 2, !tbaa !9
    %8 = load volatile i8, i8* %7, align 1, !tbaa !7
    %and16 = and i8 %8, 32
    %tobool17 = icmp eq i8 %and16, 0
    br i1 %tobool17, label %while.cond.backedge, label %if.then.18

    if.then.18: ; preds = %if.then.13
    %9 = load volatile i8, i8* %_tx_buffer_tail.i, align 1, !tbaa !1
    %idxprom.i = zext i8 %9 to i16
    %arrayidx.i = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 13, i16 %idxprom.i
    %10 = load i8, i8* %arrayidx.i, align 1, !tbaa !7
    %11 = load volatile i8, i8* %_tx_buffer_tail.i, align 1, !tbaa !1
    %add.i = add i8 %11, 1
    %rem.i = and i8 %add.i, 63
    store volatile i8 %rem.i, i8* %_tx_buffer_tail.i, align 1, !tbaa !1
    %12 = load i8*, i8** %_udr.i, align 2, !tbaa !8
    store volatile i8 %10, i8* %12, align 1, !tbaa !7
    %13 = load i8*, i8** %_ucsra, align 2, !tbaa !9
    %14 = load volatile i8, i8* %13, align 1, !tbaa !7
    %or.i = or i8 %14, 64
    store volatile i8 %or.i, i8* %13, align 1, !tbaa !7
    %15 = load volatile i8, i8* %_tx_buffer_head.i, align 1, !tbaa !10
    %16 = load volatile i8, i8* %_tx_buffer_tail.i, align 1, !tbaa !1
    %cmp.i = icmp eq i8 %15, %16
    br i1 %cmp.i, label %if.then.i, label %while.cond.backedge

    if.then.i: ; preds = %if.then.18
    %17 = load i8*, i8** %_ucsrb, align 2, !tbaa !11
    %18 = load volatile i8, i8* %17, align 1, !tbaa !7
    %and.i = and i8 %18, -33
    store volatile i8 %and.i, i8* %17, align 1, !tbaa !7
    br label %while.cond.backedge

    while.end.loopexit: ; preds = %lor.rhs
    br label %while.end

    while.end: ; preds = %while.end.loopexit, %entry
    ret void
    }

    ; Function Attrs: nounwind
    define i16 @_ZN14HardwareSerial5writeEh(%class.HardwareSerial* nocapture %this, i8 zeroext %c) unnamed_addr #1 align 2 {
    entry:
    %_tx_buffer_head = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 10
    %0 = load volatile i8, i8* %_tx_buffer_head, align 1, !tbaa !10
    %_tx_buffer_tail = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 11
    %1 = load volatile i8, i8* %_tx_buffer_tail, align 1, !tbaa !1
    %cmp = icmp eq i8 %0, %1
    br i1 %cmp, label %land.lhs.true, label %if.end

    land.lhs.true: ; preds = %entry
    %_ucsra = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 3
    %2 = load i8*, i8** %_ucsra, align 2, !tbaa !9
    %3 = load volatile i8, i8* %2, align 1, !tbaa !7
    %and = and i8 %3, 32
    %tobool = icmp eq i8 %and, 0
    br i1 %tobool, label %if.end, label %if.then

    if.then: ; preds = %land.lhs.true
    %_udr = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 6
    %4 = load i8*, i8** %_udr, align 2, !tbaa !8
    store volatile i8 %c, i8* %4, align 1, !tbaa !7
    %5 = load i8*, i8** %_ucsra, align 2, !tbaa !9
    %6 = load volatile i8, i8* %5, align 1, !tbaa !7
    %or = or i8 %6, 64
    store volatile i8 %or, i8* %5, align 1, !tbaa !7
    br label %return

    if.end: ; preds = %land.lhs.true, %entry
    %7 = load volatile i8, i8* %_tx_buffer_head, align 1, !tbaa !10
    %add = add i8 %7, 1
    %rem = and i8 %add, 63
    %8 = load volatile i8, i8* %_tx_buffer_tail, align 1, !tbaa !1
    %cmp13.32 = icmp eq i8 %rem, %8
    br i1 %cmp13.32, label %while.body.lr.ph, label %if.end.while.end_crit_edge

    if.end.while.end_crit_edge: ; preds = %if.end
    %.pre = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 4
    br label %while.end

    while.body.lr.ph: ; preds = %if.end
    %_ucsra18 = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 3
    %_udr.i = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 6
    %_ucsrb.i = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 4
    br label %while.body

    while.body: ; preds = %while.body.lr.ph, %while.cond.backedge
    %9 = load volatile i8, i8* inttoptr (i16 95 to i8*), align 1, !tbaa !7
    %tobool16 = icmp slt i8 %9, 0
    br i1 %tobool16, label %while.cond.backedge, label %if.then.17

    while.cond.backedge: ; preds = %while.body, %if.then.17, %if.then.22, %if.then.i
    %10 = load volatile i8, i8* %_tx_buffer_tail, align 1, !tbaa !1
    %cmp13 = icmp eq i8 %rem, %10
    br i1 %cmp13, label %while.body, label %while.end.loopexit

    if.then.17: ; preds = %while.body
    %11 = load i8*, i8** %_ucsra18, align 2, !tbaa !9
    %12 = load volatile i8, i8* %11, align 1, !tbaa !7
    %and20 = and i8 %12, 32
    %tobool21 = icmp eq i8 %and20, 0
    br i1 %tobool21, label %while.cond.backedge, label %if.then.22

    if.then.22: ; preds = %if.then.17
    %13 = load volatile i8, i8* %_tx_buffer_tail, align 1, !tbaa !1
    %idxprom.i = zext i8 %13 to i16
    %arrayidx.i = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 13, i16 %idxprom.i
    %14 = load i8, i8* %arrayidx.i, align 1, !tbaa !7
    %15 = load volatile i8, i8* %_tx_buffer_tail, align 1, !tbaa !1
    %add.i = add i8 %15, 1
    %rem.i = and i8 %add.i, 63
    store volatile i8 %rem.i, i8* %_tx_buffer_tail, align 1, !tbaa !1
    %16 = load i8*, i8** %_udr.i, align 2, !tbaa !8
    store volatile i8 %14, i8* %16, align 1, !tbaa !7
    %17 = load i8*, i8** %_ucsra18, align 2, !tbaa !9
    %18 = load volatile i8, i8* %17, align 1, !tbaa !7
    %or.i = or i8 %18, 64
    store volatile i8 %or.i, i8* %17, align 1, !tbaa !7
    %19 = load volatile i8, i8* %_tx_buffer_head, align 1, !tbaa !10
    %20 = load volatile i8, i8* %_tx_buffer_tail, align 1, !tbaa !1
    %cmp.i = icmp eq i8 %19, %20
    br i1 %cmp.i, label %if.then.i, label %while.cond.backedge

    if.then.i: ; preds = %if.then.22
    %21 = load i8*, i8** %_ucsrb.i, align 2, !tbaa !11
    %22 = load volatile i8, i8* %21, align 1, !tbaa !7
    %and.i = and i8 %22, -33
    store volatile i8 %and.i, i8* %21, align 1, !tbaa !7
    br label %while.cond.backedge

    while.end.loopexit: ; preds = %while.cond.backedge
    br label %while.end

    while.end: ; preds = %while.end.loopexit, %if.end.while.end_crit_edge
    %_ucsrb.pre-phi = phi i8** [ %.pre, %if.end.while.end_crit_edge ], [ %_ucsrb.i, %while.end.loopexit ]
    %23 = load volatile i8, i8* %_tx_buffer_head, align 1, !tbaa !10
    %idxprom = zext i8 %23 to i16
    %arrayidx = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 13, i16 %idxprom
    store i8 %c, i8* %arrayidx, align 1, !tbaa !7
    store volatile i8 %rem, i8* %_tx_buffer_head, align 1, !tbaa !10
    %24 = load i8*, i8** %_ucsrb.pre-phi, align 2, !tbaa !11
    %25 = load volatile i8, i8* %24, align 1, !tbaa !7
    %or28 = or i8 %25, 32
    store volatile i8 %or28, i8* %24, align 1, !tbaa !7
    %_written = getelementptr inbounds %class.HardwareSerial, %class.HardwareSerial* %this, i16 0, i32 7
    store i8 1, i8* %_written, align 1, !tbaa !14
    br label %return

    return: ; preds = %while.end, %if.then
    ret i16 1
    }

    declare i16 @_ZN5Print5writeEPKhj(%class.Print*, i8*, i16) #0

    attributes #0 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #1 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }

    !llvm.ident = !{!0}

    !0 = !{!"clang version 3.7.0 (https://github.com/llvm-mirror/clang.git 287e62c84a1ccd74fbca46bfc13e364e314d4b41) (https://github.com/llvm-mirror/llvm.git aaab572fc38b4438e769e2fd6b91963be11db7b2)"}
    !1 = !{!2, !4, i64 28}
    !2 = !{!"_ZTS14HardwareSerial", !3, i64 12, !3, i64 14, !3, i64 16, !3, i64 18, !3, i64 20, !3, i64 22, !6, i64 24, !4, i64 25, !4, i64 26, !4, i64 27, !4, i64 28, !4, i64 29, !4, i64 93}
    !3 = !{!"any pointer", !4, i64 0}
    !4 = !{!"omnipotent char", !5, i64 0}
    !5 = !{!"Simple C/C++ TBAA"}
    !6 = !{!"bool", !4, i64 0}
    !7 = !{!4, !4, i64 0}
    !8 = !{!2, !3, i64 22}
    !9 = !{!2, !3, i64 16}
    !10 = !{!2, !4, i64 27}
    !11 = !{!2, !3, i64 18}
    !12 = !{!2, !3, i64 12}
    !13 = !{!2, !3, i64 14}
    !14 = !{!2, !6, i64 24}
    !15 = !{!2, !3, i64 20}
    !16 = !{!2, !4, i64 26}
    !17 = !{!2, !4, i64 25}
    !18 = !{i8 0, i8 2}
    7 changes: 7 additions & 0 deletions HardwareSerial1.ll
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,7 @@
    ; ModuleID = './HardwareSerial1.cpp'
    target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-i64:8:8-f32:8:8-f64:8:8-n8"
    target triple = "avr"

    !llvm.ident = !{!0}

    !0 = !{!"clang version 3.7.0 (https://github.com/llvm-mirror/clang.git 287e62c84a1ccd74fbca46bfc13e364e314d4b41) (https://github.com/llvm-mirror/llvm.git aaab572fc38b4438e769e2fd6b91963be11db7b2)"}
    7 changes: 7 additions & 0 deletions HardwareSerial2.ll
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,7 @@
    ; ModuleID = './HardwareSerial2.cpp'
    target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-i64:8:8-f32:8:8-f64:8:8-n8"
    target triple = "avr"

    !llvm.ident = !{!0}

    !0 = !{!"clang version 3.7.0 (https://github.com/llvm-mirror/clang.git 287e62c84a1ccd74fbca46bfc13e364e314d4b41) (https://github.com/llvm-mirror/llvm.git aaab572fc38b4438e769e2fd6b91963be11db7b2)"}
    7 changes: 7 additions & 0 deletions HardwareSerial3.ll
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,7 @@
    ; ModuleID = './HardwareSerial3.cpp'
    target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-i64:8:8-f32:8:8-f64:8:8-n8"
    target triple = "avr"

    !llvm.ident = !{!0}

    !0 = !{!"clang version 3.7.0 (https://github.com/llvm-mirror/clang.git 287e62c84a1ccd74fbca46bfc13e364e314d4b41) (https://github.com/llvm-mirror/llvm.git aaab572fc38b4438e769e2fd6b91963be11db7b2)"}
    155 changes: 155 additions & 0 deletions IPAddress.ll
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,155 @@
    ; ModuleID = './IPAddress.cpp'
    target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-i64:8:8-f32:8:8-f64:8:8-n8"
    target triple = "avr"

    %class.IPAddress = type { %class.Printable, %union.anon }
    %class.Printable = type { i32 (...)** }
    %union.anon = type { [4 x i8] }
    %class.Print = type { i32 (...)**, i16 }

    $_ZTS9Printable = comdat any

    $_ZTI9Printable = comdat any

    @_ZTV9IPAddress = unnamed_addr constant [3 x i8*] [i8* null, i8* bitcast ({ i8*, i8*, i8* }* @_ZTI9IPAddress to i8*), i8* bitcast (i16 (%class.IPAddress*, %class.Print*)* @_ZNK9IPAddress7printToER5Print to i8*)], align 2
    @_ZTVN10__cxxabiv120__si_class_type_infoE = external global i8*
    @_ZTS9IPAddress = constant [11 x i8] c"9IPAddress\00"
    @_ZTVN10__cxxabiv117__class_type_infoE = external global i8*
    @_ZTS9Printable = linkonce_odr constant [11 x i8] c"9Printable\00", comdat
    @_ZTI9Printable = linkonce_odr constant { i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv117__class_type_infoE, i16 2) to i8*), i8* getelementptr inbounds ([11 x i8], [11 x i8]* @_ZTS9Printable, i32 0, i32 0) }, comdat
    @_ZTI9IPAddress = constant { i8*, i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv120__si_class_type_infoE, i16 2) to i8*), i8* getelementptr inbounds ([11 x i8], [11 x i8]* @_ZTS9IPAddress, i32 0, i32 0), i8* bitcast ({ i8*, i8* }* @_ZTI9Printable to i8*) }
    @llvm.global_ctors = appending global [0 x { i32, void ()*, i8* }] zeroinitializer

    @_ZN9IPAddressC1Ev = alias void (%class.IPAddress*)* @_ZN9IPAddressC2Ev
    @_ZN9IPAddressC1Ehhhh = alias void (%class.IPAddress*, i8, i8, i8, i8)* @_ZN9IPAddressC2Ehhhh
    @_ZN9IPAddressC1Em = alias void (%class.IPAddress*, i32)* @_ZN9IPAddressC2Em
    @_ZN9IPAddressC1EPKh = alias void (%class.IPAddress*, i8*)* @_ZN9IPAddressC2EPKh

    ; Function Attrs: nounwind
    define void @_ZN9IPAddressC2Ev(%class.IPAddress* nocapture %this) unnamed_addr #0 align 2 {
    entry:
    %0 = getelementptr inbounds %class.IPAddress, %class.IPAddress* %this, i16 0, i32 0, i32 0
    store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV9IPAddress, i16 0, i16 2) to i32 (...)**), i32 (...)*** %0, align 1, !tbaa !1
    %_address2 = getelementptr inbounds %class.IPAddress, %class.IPAddress* %this, i16 0, i32 1
    %dword = bitcast %union.anon* %_address2 to i32*
    store i32 0, i32* %dword, align 2, !tbaa !4
    ret void
    }

    ; Function Attrs: nounwind
    define void @_ZN9IPAddressC2Ehhhh(%class.IPAddress* nocapture %this, i8 zeroext %first_octet, i8 zeroext %second_octet, i8 zeroext %third_octet, i8 zeroext %fourth_octet) unnamed_addr #0 align 2 {
    entry:
    %0 = getelementptr inbounds %class.IPAddress, %class.IPAddress* %this, i16 0, i32 0, i32 0
    store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV9IPAddress, i16 0, i16 2) to i32 (...)**), i32 (...)*** %0, align 1, !tbaa !1
    %arrayidx = getelementptr inbounds %class.IPAddress, %class.IPAddress* %this, i16 0, i32 1, i32 0, i16 0
    store i8 %first_octet, i8* %arrayidx, align 1, !tbaa !7
    %arrayidx5 = getelementptr inbounds %class.IPAddress, %class.IPAddress* %this, i16 0, i32 1, i32 0, i16 1
    store i8 %second_octet, i8* %arrayidx5, align 1, !tbaa !7
    %arrayidx8 = getelementptr inbounds %class.IPAddress, %class.IPAddress* %this, i16 0, i32 1, i32 0, i16 2
    store i8 %third_octet, i8* %arrayidx8, align 1, !tbaa !7
    %arrayidx11 = getelementptr inbounds %class.IPAddress, %class.IPAddress* %this, i16 0, i32 1, i32 0, i16 3
    store i8 %fourth_octet, i8* %arrayidx11, align 1, !tbaa !7
    ret void
    }

    ; Function Attrs: nounwind
    define void @_ZN9IPAddressC2Em(%class.IPAddress* nocapture %this, i32 %address) unnamed_addr #0 align 2 {
    entry:
    %0 = getelementptr inbounds %class.IPAddress, %class.IPAddress* %this, i16 0, i32 0, i32 0
    store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV9IPAddress, i16 0, i16 2) to i32 (...)**), i32 (...)*** %0, align 1, !tbaa !1
    %_address2 = getelementptr inbounds %class.IPAddress, %class.IPAddress* %this, i16 0, i32 1
    %dword = bitcast %union.anon* %_address2 to i32*
    store i32 %address, i32* %dword, align 2, !tbaa !4
    ret void
    }

    ; Function Attrs: nounwind
    define void @_ZN9IPAddressC2EPKh(%class.IPAddress* nocapture %this, i8* nocapture readonly %address) unnamed_addr #0 align 2 {
    entry:
    %0 = getelementptr inbounds %class.IPAddress, %class.IPAddress* %this, i16 0, i32 0, i32 0
    store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV9IPAddress, i16 0, i16 2) to i32 (...)**), i32 (...)*** %0, align 1, !tbaa !1
    %1 = getelementptr inbounds %class.IPAddress, %class.IPAddress* %this, i16 0, i32 1, i32 0, i16 0
    %2 = bitcast i8* %address to i32*
    %3 = bitcast i8* %1 to i32*
    %4 = load i32, i32* %2, align 1
    store i32 %4, i32* %3, align 1
    ret void
    }

    ; Function Attrs: nounwind
    define dereferenceable(6) %class.IPAddress* @_ZN9IPAddressaSEPKh(%class.IPAddress* %this, i8* nocapture readonly %address) #0 align 2 {
    entry:
    %0 = getelementptr inbounds %class.IPAddress, %class.IPAddress* %this, i16 0, i32 1, i32 0, i16 0
    %1 = bitcast i8* %address to i32*
    %2 = bitcast i8* %0 to i32*
    %3 = load i32, i32* %1, align 1
    store i32 %3, i32* %2, align 1
    ret %class.IPAddress* %this
    }

    ; Function Attrs: nounwind
    define dereferenceable(6) %class.IPAddress* @_ZN9IPAddressaSEm(%class.IPAddress* %this, i32 %address) #0 align 2 {
    entry:
    %_address = getelementptr inbounds %class.IPAddress, %class.IPAddress* %this, i16 0, i32 1
    %dword = bitcast %union.anon* %_address to i32*
    store i32 %address, i32* %dword, align 2, !tbaa !4
    ret %class.IPAddress* %this
    }

    ; Function Attrs: nounwind readonly
    define zeroext i1 @_ZNK9IPAddresseqEPKh(%class.IPAddress* nocapture readonly %this, i8* nocapture readonly %addr) #1 align 2 {
    entry:
    %arraydecay = getelementptr inbounds %class.IPAddress, %class.IPAddress* %this, i16 0, i32 1, i32 0, i16 0
    %call = tail call i16 @memcmp(i8* %addr, i8* %arraydecay, i16 4) #3
    %cmp = icmp eq i16 %call, 0
    ret i1 %cmp
    }

    ; Function Attrs: nounwind readonly
    declare i16 @memcmp(i8* nocapture, i8* nocapture, i16) #1

    define i16 @_ZNK9IPAddress7printToER5Print(%class.IPAddress* nocapture readonly %this, %class.Print* dereferenceable(4) %p) unnamed_addr #2 align 2 {
    entry:
    %arrayidx = getelementptr inbounds %class.IPAddress, %class.IPAddress* %this, i16 0, i32 1, i32 0, i16 0
    %0 = load i8, i8* %arrayidx, align 1, !tbaa !7
    %call = tail call i16 @_ZN5Print5printEhi(%class.Print* nonnull %p, i8 zeroext %0, i16 10)
    %call2 = tail call i16 @_ZN5Print5printEc(%class.Print* nonnull %p, i8 signext 46)
    %add3 = add i16 %call, %call2
    %arrayidx.1 = getelementptr inbounds %class.IPAddress, %class.IPAddress* %this, i16 0, i32 1, i32 0, i16 1
    %1 = load i8, i8* %arrayidx.1, align 1, !tbaa !7
    %call.1 = tail call i16 @_ZN5Print5printEhi(%class.Print* nonnull %p, i8 zeroext %1, i16 10)
    %add.1 = add i16 %call.1, %add3
    %call2.1 = tail call i16 @_ZN5Print5printEc(%class.Print* nonnull %p, i8 signext 46)
    %add3.1 = add i16 %add.1, %call2.1
    %arrayidx.2 = getelementptr inbounds %class.IPAddress, %class.IPAddress* %this, i16 0, i32 1, i32 0, i16 2
    %2 = load i8, i8* %arrayidx.2, align 1, !tbaa !7
    %call.2 = tail call i16 @_ZN5Print5printEhi(%class.Print* nonnull %p, i8 zeroext %2, i16 10)
    %add.2 = add i16 %call.2, %add3.1
    %call2.2 = tail call i16 @_ZN5Print5printEc(%class.Print* nonnull %p, i8 signext 46)
    %add3.2 = add i16 %add.2, %call2.2
    %arrayidx6 = getelementptr inbounds %class.IPAddress, %class.IPAddress* %this, i16 0, i32 1, i32 0, i16 3
    %3 = load i8, i8* %arrayidx6, align 1, !tbaa !7
    %call7 = tail call i16 @_ZN5Print5printEhi(%class.Print* nonnull %p, i8 zeroext %3, i16 10)
    %add8 = add i16 %call7, %add3.2
    ret i16 %add8
    }

    declare i16 @_ZN5Print5printEhi(%class.Print*, i8 zeroext, i16) #2

    declare i16 @_ZN5Print5printEc(%class.Print*, i8 signext) #2

    attributes #0 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #1 = { nounwind readonly "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #2 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #3 = { nounwind readonly }

    !llvm.ident = !{!0}

    !0 = !{!"clang version 3.7.0 (https://github.com/llvm-mirror/clang.git 287e62c84a1ccd74fbca46bfc13e364e314d4b41) (https://github.com/llvm-mirror/llvm.git aaab572fc38b4438e769e2fd6b91963be11db7b2)"}
    !1 = !{!2, !2, i64 0}
    !2 = !{!"vtable pointer", !3, i64 0}
    !3 = !{!"Simple C/C++ TBAA"}
    !4 = !{!5, !5, i64 0}
    !5 = !{!"long", !6, i64 0}
    !6 = !{!"omnipotent char", !3, i64 0}
    !7 = !{!6, !6, i64 0}
    1,086 changes: 1,086 additions & 0 deletions Print.ll
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,1086 @@
    ; ModuleID = './Print.cpp'
    target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-i64:8:8-f32:8:8-f64:8:8-n8"
    target triple = "avr"

    %class.Print = type { i32 (...)**, i16 }
    %class.__FlashStringHelper = type opaque
    %class.String = type { i8*, i16, i16 }
    %class.Printable = type { i32 (...)** }

    @.str = private unnamed_addr constant [4 x i8] c"nan\00", align 1
    @.str.1 = private unnamed_addr constant [4 x i8] c"inf\00", align 1
    @.str.2 = private unnamed_addr constant [4 x i8] c"ovf\00", align 1
    @.str.3 = private unnamed_addr constant [2 x i8] c".\00", align 1
    @_ZTV5Print = unnamed_addr constant [4 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI5Print to i8*), i8* bitcast (void ()* @__cxa_pure_virtual to i8*), i8* bitcast (i16 (%class.Print*, i8*, i16)* @_ZN5Print5writeEPKhj to i8*)], align 2
    @_ZTVN10__cxxabiv117__class_type_infoE = external global i8*
    @_ZTS5Print = constant [7 x i8] c"5Print\00"
    @_ZTI5Print = constant { i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv117__class_type_infoE, i16 2) to i8*), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @_ZTS5Print, i32 0, i32 0) }

    define i16 @_ZN5Print5writeEPKhj(%class.Print* %this, i8* nocapture readonly %buffer, i16 %size) unnamed_addr #0 align 2 {
    entry:
    %tobool.4 = icmp eq i16 %size, 0
    br i1 %tobool.4, label %while.end, label %while.body.lr.ph

    while.body.lr.ph: ; preds = %entry
    %0 = bitcast %class.Print* %this to i16 (%class.Print*, i8)***
    br label %while.body

    while.body: ; preds = %while.body.lr.ph, %while.body
    %n.07 = phi i16 [ 0, %while.body.lr.ph ], [ %add, %while.body ]
    %size.addr.06 = phi i16 [ %size, %while.body.lr.ph ], [ %dec, %while.body ]
    %buffer.addr.05 = phi i8* [ %buffer, %while.body.lr.ph ], [ %incdec.ptr, %while.body ]
    %dec = add i16 %size.addr.06, -1
    %vtable = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %0, align 1, !tbaa !1
    %1 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable, align 1
    %incdec.ptr = getelementptr inbounds i8, i8* %buffer.addr.05, i16 1
    %2 = load i8, i8* %buffer.addr.05, align 1, !tbaa !4
    %call = tail call i16 %1(%class.Print* %this, i8 zeroext %2)
    %add = add i16 %call, %n.07
    %tobool = icmp eq i16 %dec, 0
    br i1 %tobool, label %while.end.loopexit, label %while.body

    while.end.loopexit: ; preds = %while.body
    %add.lcssa = phi i16 [ %add, %while.body ]
    br label %while.end

    while.end: ; preds = %while.end.loopexit, %entry
    %n.0.lcssa = phi i16 [ 0, %entry ], [ %add.lcssa, %while.end.loopexit ]
    ret i16 %n.0.lcssa
    }

    ; Function Attrs: nounwind
    declare void @llvm.lifetime.start(i64, i8* nocapture) #1

    ; Function Attrs: nounwind
    declare void @llvm.lifetime.end(i64, i8* nocapture) #1

    define i16 @_ZN5Print5printEPK19__FlashStringHelper(%class.Print* %this, %class.__FlashStringHelper* %ifsh) #0 align 2 {
    entry:
    %0 = ptrtoint %class.__FlashStringHelper* %ifsh to i16
    %1 = tail call i8 asm sideeffect "lpm\0A\09mov $0, r0\0A\09", "=r,z,~{r0}"(i16 %0) #1, !srcloc !6
    %cmp.9 = icmp eq i8 %1, 0
    br i1 %cmp.9, label %while.end, label %cleanup.thread.lr.ph

    cleanup.thread.lr.ph: ; preds = %entry
    %2 = bitcast %class.__FlashStringHelper* %ifsh to i8*
    %3 = bitcast %class.Print* %this to i16 (%class.Print*, i8)***
    br label %cleanup.thread

    cleanup.thread: ; preds = %cleanup.thread.lr.ph, %cleanup.thread
    %4 = phi i8 [ %1, %cleanup.thread.lr.ph ], [ %7, %cleanup.thread ]
    %p.011 = phi i8* [ %2, %cleanup.thread.lr.ph ], [ %incdec.ptr, %cleanup.thread ]
    %n.010 = phi i16 [ 0, %cleanup.thread.lr.ph ], [ %add, %cleanup.thread ]
    %incdec.ptr = getelementptr inbounds i8, i8* %p.011, i16 1
    %vtable = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %3, align 1, !tbaa !1
    %5 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable, align 1
    %call = tail call i16 %5(%class.Print* %this, i8 zeroext %4)
    %add = add i16 %call, %n.010
    %6 = ptrtoint i8* %incdec.ptr to i16
    %7 = tail call i8 asm sideeffect "lpm\0A\09mov $0, r0\0A\09", "=r,z,~{r0}"(i16 %6) #1, !srcloc !6
    %cmp = icmp eq i8 %7, 0
    br i1 %cmp, label %while.end.loopexit, label %cleanup.thread

    while.end.loopexit: ; preds = %cleanup.thread
    %add.lcssa = phi i16 [ %add, %cleanup.thread ]
    br label %while.end

    while.end: ; preds = %while.end.loopexit, %entry
    %n.0.lcssa = phi i16 [ 0, %entry ], [ %add.lcssa, %while.end.loopexit ]
    ret i16 %n.0.lcssa
    }

    define i16 @_ZN5Print5printERK6String(%class.Print* %this, %class.String* nocapture readonly dereferenceable(6) %s) #0 align 2 {
    entry:
    %buffer.i = getelementptr inbounds %class.String, %class.String* %s, i16 0, i32 0
    %0 = load i8*, i8** %buffer.i, align 2, !tbaa !7
    %len.i = getelementptr inbounds %class.String, %class.String* %s, i16 0, i32 2
    %1 = load i16, i16* %len.i, align 2, !tbaa !11
    %2 = bitcast %class.Print* %this to i16 (%class.Print*, i8*, i16)***
    %vtable.i = load i16 (%class.Print*, i8*, i16)**, i16 (%class.Print*, i8*, i16)*** %2, align 1, !tbaa !1
    %vfn.i = getelementptr inbounds i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vtable.i, i16 1
    %3 = load i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vfn.i, align 1
    %call.i = tail call i16 %3(%class.Print* %this, i8* %0, i16 %1)
    ret i16 %call.i
    }

    define i16 @_ZN5Print5printEPKc(%class.Print* %this, i8* %str) #0 align 2 {
    entry:
    %cmp.i = icmp eq i8* %str, null
    br i1 %cmp.i, label %_ZN5Print5writeEPKc.exit, label %if.end.i

    if.end.i: ; preds = %entry
    %0 = bitcast %class.Print* %this to i16 (%class.Print*, i8*, i16)***
    %vtable.i = load i16 (%class.Print*, i8*, i16)**, i16 (%class.Print*, i8*, i16)*** %0, align 1, !tbaa !1
    %vfn.i = getelementptr inbounds i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vtable.i, i16 1
    %1 = load i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vfn.i, align 1
    %call.i = tail call i16 @strlen(i8* %str) #4
    %call2.i = tail call i16 %1(%class.Print* %this, i8* %str, i16 %call.i)
    br label %_ZN5Print5writeEPKc.exit

    _ZN5Print5writeEPKc.exit: ; preds = %entry, %if.end.i
    %retval.0.i = phi i16 [ %call2.i, %if.end.i ], [ 0, %entry ]
    ret i16 %retval.0.i
    }

    define i16 @_ZN5Print5printEc(%class.Print* %this, i8 signext %c) #0 align 2 {
    entry:
    %0 = bitcast %class.Print* %this to i16 (%class.Print*, i8)***
    %vtable = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %0, align 1, !tbaa !1
    %1 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable, align 1
    %call = tail call i16 %1(%class.Print* %this, i8 zeroext %c)
    ret i16 %call
    }

    define i16 @_ZN5Print5printEhi(%class.Print* %this, i8 zeroext %b, i16 %base) #0 align 2 {
    entry:
    %buf.i.i = alloca [33 x i8], align 1
    %cmp.i = icmp eq i16 %base, 0
    br i1 %cmp.i, label %if.then.i, label %if.else.i

    if.then.i: ; preds = %entry
    %0 = bitcast %class.Print* %this to i16 (%class.Print*, i8)***
    %vtable.i = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %0, align 1, !tbaa !1
    %1 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i, align 1
    %call.i = tail call i16 %1(%class.Print* %this, i8 zeroext %b)
    br label %_ZN5Print5printEmi.exit

    if.else.i: ; preds = %entry
    %conv = zext i8 %b to i32
    %conv2.i = trunc i16 %base to i8
    %2 = getelementptr inbounds [33 x i8], [33 x i8]* %buf.i.i, i16 0, i16 0
    call void @llvm.lifetime.start(i64 33, i8* %2) #1
    %arrayidx.i.i = getelementptr inbounds [33 x i8], [33 x i8]* %buf.i.i, i16 0, i16 32
    store i8 0, i8* %arrayidx.i.i, align 1, !tbaa !4
    %cmp.i.i = icmp ult i8 %conv2.i, 2
    %conv2.mask.i = and i16 %base, 255
    %3 = zext i16 %conv2.mask.i to i32
    %conv2.i.i = select i1 %cmp.i.i, i32 10, i32 %3
    br label %do.body.i.i

    do.body.i.i: ; preds = %do.body.i.i, %if.else.i
    %str.0.i.i = phi i8* [ %incdec.ptr.i.i, %do.body.i.i ], [ %arrayidx.i.i, %if.else.i ]
    %n.addr.0.i.i = phi i32 [ %div.i.i, %do.body.i.i ], [ %conv, %if.else.i ]
    %div.i.i = udiv i32 %n.addr.0.i.i, %conv2.i.i
    %mul.i.i = mul i32 %div.i.i, %conv2.i.i
    %sub.i.i = sub i32 %n.addr.0.i.i, %mul.i.i
    %conv4.i.i = trunc i32 %sub.i.i to i8
    %cmp6.i.i = icmp slt i8 %conv4.i.i, 10
    %cond.v.i.i = select i1 %cmp6.i.i, i8 48, i8 55
    %cond.i.i = add i8 %cond.v.i.i, %conv4.i.i
    %incdec.ptr.i.i = getelementptr inbounds i8, i8* %str.0.i.i, i16 -1
    store i8 %cond.i.i, i8* %incdec.ptr.i.i, align 1, !tbaa !4
    %tobool.i.i = icmp eq i32 %div.i.i, 0
    br i1 %tobool.i.i, label %_ZN5Print11printNumberEmh.exit.i, label %do.body.i.i

    _ZN5Print11printNumberEmh.exit.i: ; preds = %do.body.i.i
    %incdec.ptr.i.i.lcssa = phi i8* [ %incdec.ptr.i.i, %do.body.i.i ]
    %4 = bitcast %class.Print* %this to i16 (%class.Print*, i8*, i16)***
    %vtable.i.i.i = load i16 (%class.Print*, i8*, i16)**, i16 (%class.Print*, i8*, i16)*** %4, align 1, !tbaa !1
    %vfn.i.i.i = getelementptr inbounds i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vtable.i.i.i, i16 1
    %5 = load i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vfn.i.i.i, align 1
    %call.i.i.i = call i16 @strlen(i8* %incdec.ptr.i.i.lcssa) #4
    %call2.i.i.i = call i16 %5(%class.Print* %this, i8* %incdec.ptr.i.i.lcssa, i16 %call.i.i.i)
    call void @llvm.lifetime.end(i64 33, i8* %2) #1
    br label %_ZN5Print5printEmi.exit

    _ZN5Print5printEmi.exit: ; preds = %if.then.i, %_ZN5Print11printNumberEmh.exit.i
    %retval.0.i = phi i16 [ %call.i, %if.then.i ], [ %call2.i.i.i, %_ZN5Print11printNumberEmh.exit.i ]
    ret i16 %retval.0.i
    }

    define i16 @_ZN5Print5printEmi(%class.Print* %this, i32 %n, i16 %base) #0 align 2 {
    entry:
    %buf.i = alloca [33 x i8], align 1
    %cmp = icmp eq i16 %base, 0
    br i1 %cmp, label %if.then, label %if.else

    if.then: ; preds = %entry
    %0 = bitcast %class.Print* %this to i16 (%class.Print*, i8)***
    %vtable = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %0, align 1, !tbaa !1
    %1 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable, align 1
    %conv = trunc i32 %n to i8
    %call = tail call i16 %1(%class.Print* %this, i8 zeroext %conv)
    br label %return

    if.else: ; preds = %entry
    %conv2 = trunc i16 %base to i8
    %2 = getelementptr inbounds [33 x i8], [33 x i8]* %buf.i, i16 0, i16 0
    call void @llvm.lifetime.start(i64 33, i8* %2) #1
    %arrayidx.i = getelementptr inbounds [33 x i8], [33 x i8]* %buf.i, i16 0, i16 32
    store i8 0, i8* %arrayidx.i, align 1, !tbaa !4
    %cmp.i = icmp ult i8 %conv2, 2
    %conv2.mask = and i16 %base, 255
    %3 = zext i16 %conv2.mask to i32
    %conv2.i = select i1 %cmp.i, i32 10, i32 %3
    br label %do.body.i

    do.body.i: ; preds = %do.body.i, %if.else
    %str.0.i = phi i8* [ %incdec.ptr.i, %do.body.i ], [ %arrayidx.i, %if.else ]
    %n.addr.0.i = phi i32 [ %div.i, %do.body.i ], [ %n, %if.else ]
    %div.i = udiv i32 %n.addr.0.i, %conv2.i
    %mul.i = mul i32 %div.i, %conv2.i
    %sub.i = sub i32 %n.addr.0.i, %mul.i
    %conv4.i = trunc i32 %sub.i to i8
    %cmp6.i = icmp slt i8 %conv4.i, 10
    %cond.v.i = select i1 %cmp6.i, i8 48, i8 55
    %cond.i = add i8 %cond.v.i, %conv4.i
    %incdec.ptr.i = getelementptr inbounds i8, i8* %str.0.i, i16 -1
    store i8 %cond.i, i8* %incdec.ptr.i, align 1, !tbaa !4
    %tobool.i = icmp eq i32 %div.i, 0
    br i1 %tobool.i, label %_ZN5Print11printNumberEmh.exit, label %do.body.i

    _ZN5Print11printNumberEmh.exit: ; preds = %do.body.i
    %incdec.ptr.i.lcssa = phi i8* [ %incdec.ptr.i, %do.body.i ]
    %4 = bitcast %class.Print* %this to i16 (%class.Print*, i8*, i16)***
    %vtable.i.i = load i16 (%class.Print*, i8*, i16)**, i16 (%class.Print*, i8*, i16)*** %4, align 1, !tbaa !1
    %vfn.i.i = getelementptr inbounds i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vtable.i.i, i16 1
    %5 = load i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vfn.i.i, align 1
    %call.i.i = call i16 @strlen(i8* %incdec.ptr.i.lcssa) #4
    %call2.i.i = call i16 %5(%class.Print* %this, i8* %incdec.ptr.i.lcssa, i16 %call.i.i)
    call void @llvm.lifetime.end(i64 33, i8* %2) #1
    br label %return

    return: ; preds = %_ZN5Print11printNumberEmh.exit, %if.then
    %retval.0 = phi i16 [ %call, %if.then ], [ %call2.i.i, %_ZN5Print11printNumberEmh.exit ]
    ret i16 %retval.0
    }

    define i16 @_ZN5Print5printEii(%class.Print* %this, i16 %n, i16 %base) #0 align 2 {
    entry:
    %conv = sext i16 %n to i32
    %call = tail call i16 @_ZN5Print5printEli(%class.Print* %this, i32 %conv, i16 %base)
    ret i16 %call
    }

    define i16 @_ZN5Print5printEli(%class.Print* %this, i32 %n, i16 %base) #0 align 2 {
    entry:
    %buf.i = alloca [33 x i8], align 1
    switch i16 %base, label %if.else.9 [
    i16 0, label %if.then
    i16 10, label %if.then.3
    ]

    if.then: ; preds = %entry
    %0 = bitcast %class.Print* %this to i16 (%class.Print*, i8)***
    %vtable = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %0, align 1, !tbaa !1
    %1 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable, align 1
    %conv = trunc i32 %n to i8
    %call = tail call i16 %1(%class.Print* %this, i8 zeroext %conv)
    br label %return

    if.then.3: ; preds = %entry
    %cmp4 = icmp slt i32 %n, 0
    br i1 %cmp4, label %if.then.5, label %if.end

    if.then.5: ; preds = %if.then.3
    %2 = bitcast %class.Print* %this to i16 (%class.Print*, i8)***
    %vtable.i = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %2, align 1, !tbaa !1
    %3 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i, align 1
    %call.i = tail call i16 %3(%class.Print* %this, i8 zeroext 45)
    %sub = sub nsw i32 0, %n
    %4 = getelementptr inbounds [33 x i8], [33 x i8]* %buf.i, i16 0, i16 0
    call void @llvm.lifetime.start(i64 33, i8* %4) #1
    %arrayidx.i = getelementptr inbounds [33 x i8], [33 x i8]* %buf.i, i16 0, i16 32
    store i8 0, i8* %arrayidx.i, align 1, !tbaa !4
    br label %do.body.i

    do.body.i: ; preds = %do.body.i, %if.then.5
    %str.0.i = phi i8* [ %incdec.ptr.i, %do.body.i ], [ %arrayidx.i, %if.then.5 ]
    %n.addr.0.i = phi i32 [ %div.i, %do.body.i ], [ %sub, %if.then.5 ]
    %div.i = udiv i32 %n.addr.0.i, 10
    %5 = mul i32 %div.i, -10
    %sub.i = add i32 %5, %n.addr.0.i
    %conv4.i = trunc i32 %sub.i to i8
    %cmp6.i = icmp slt i8 %conv4.i, 10
    %cond.v.i = select i1 %cmp6.i, i8 48, i8 55
    %cond.i = add i8 %cond.v.i, %conv4.i
    %incdec.ptr.i = getelementptr inbounds i8, i8* %str.0.i, i16 -1
    store i8 %cond.i, i8* %incdec.ptr.i, align 1, !tbaa !4
    %6 = icmp ult i32 %n.addr.0.i, 10
    br i1 %6, label %_ZN5Print11printNumberEmh.exit, label %do.body.i

    _ZN5Print11printNumberEmh.exit: ; preds = %do.body.i
    %incdec.ptr.i.lcssa = phi i8* [ %incdec.ptr.i, %do.body.i ]
    %7 = bitcast %class.Print* %this to i16 (%class.Print*, i8*, i16)***
    %vtable.i.i = load i16 (%class.Print*, i8*, i16)**, i16 (%class.Print*, i8*, i16)*** %7, align 1, !tbaa !1
    %vfn.i.i = getelementptr inbounds i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vtable.i.i, i16 1
    %8 = load i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vfn.i.i, align 1
    %call.i.i = call i16 @strlen(i8* %incdec.ptr.i.lcssa) #4
    %call2.i.i = call i16 %8(%class.Print* %this, i8* %incdec.ptr.i.lcssa, i16 %call.i.i)
    call void @llvm.lifetime.end(i64 33, i8* %4) #1
    %add = add i16 %call2.i.i, %call.i
    br label %return

    if.end: ; preds = %if.then.3
    %9 = getelementptr inbounds [33 x i8], [33 x i8]* %buf.i, i16 0, i16 0
    call void @llvm.lifetime.start(i64 33, i8* %9) #1
    %arrayidx.i.20 = getelementptr inbounds [33 x i8], [33 x i8]* %buf.i, i16 0, i16 32
    store i8 0, i8* %arrayidx.i.20, align 1, !tbaa !4
    br label %do.body.i.32

    do.body.i.32: ; preds = %do.body.i.32, %if.end
    %str.0.i.21 = phi i8* [ %incdec.ptr.i.30, %do.body.i.32 ], [ %arrayidx.i.20, %if.end ]
    %n.addr.0.i.22 = phi i32 [ %div.i.23, %do.body.i.32 ], [ %n, %if.end ]
    %div.i.23 = udiv i32 %n.addr.0.i.22, 10
    %10 = mul i32 %div.i.23, -10
    %sub.i.25 = add i32 %10, %n.addr.0.i.22
    %conv4.i.26 = trunc i32 %sub.i.25 to i8
    %cmp6.i.27 = icmp slt i8 %conv4.i.26, 10
    %cond.v.i.28 = select i1 %cmp6.i.27, i8 48, i8 55
    %cond.i.29 = add i8 %cond.v.i.28, %conv4.i.26
    %incdec.ptr.i.30 = getelementptr inbounds i8, i8* %str.0.i.21, i16 -1
    store i8 %cond.i.29, i8* %incdec.ptr.i.30, align 1, !tbaa !4
    %11 = icmp ult i32 %n.addr.0.i.22, 10
    br i1 %11, label %_ZN5Print11printNumberEmh.exit37, label %do.body.i.32

    _ZN5Print11printNumberEmh.exit37: ; preds = %do.body.i.32
    %incdec.ptr.i.30.lcssa = phi i8* [ %incdec.ptr.i.30, %do.body.i.32 ]
    %12 = bitcast %class.Print* %this to i16 (%class.Print*, i8*, i16)***
    %vtable.i.i.33 = load i16 (%class.Print*, i8*, i16)**, i16 (%class.Print*, i8*, i16)*** %12, align 1, !tbaa !1
    %vfn.i.i.34 = getelementptr inbounds i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vtable.i.i.33, i16 1
    %13 = load i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vfn.i.i.34, align 1
    %call.i.i.35 = call i16 @strlen(i8* %incdec.ptr.i.30.lcssa) #4
    %call2.i.i.36 = call i16 %13(%class.Print* %this, i8* %incdec.ptr.i.30.lcssa, i16 %call.i.i.35)
    call void @llvm.lifetime.end(i64 33, i8* %9) #1
    br label %return

    if.else.9: ; preds = %entry
    %conv10 = trunc i16 %base to i8
    %14 = getelementptr inbounds [33 x i8], [33 x i8]* %buf.i, i16 0, i16 0
    call void @llvm.lifetime.start(i64 33, i8* %14) #1
    %arrayidx.i.39 = getelementptr inbounds [33 x i8], [33 x i8]* %buf.i, i16 0, i16 32
    store i8 0, i8* %arrayidx.i.39, align 1, !tbaa !4
    %cmp.i = icmp ult i8 %conv10, 2
    %conv10.mask = and i16 %base, 255
    %15 = zext i16 %conv10.mask to i32
    %conv2.i = select i1 %cmp.i, i32 10, i32 %15
    br label %do.body.i.51

    do.body.i.51: ; preds = %do.body.i.51, %if.else.9
    %str.0.i.40 = phi i8* [ %incdec.ptr.i.49, %do.body.i.51 ], [ %arrayidx.i.39, %if.else.9 ]
    %n.addr.0.i.41 = phi i32 [ %div.i.42, %do.body.i.51 ], [ %n, %if.else.9 ]
    %div.i.42 = udiv i32 %n.addr.0.i.41, %conv2.i
    %mul.i.43 = mul i32 %div.i.42, %conv2.i
    %sub.i.44 = sub i32 %n.addr.0.i.41, %mul.i.43
    %conv4.i.45 = trunc i32 %sub.i.44 to i8
    %cmp6.i.46 = icmp slt i8 %conv4.i.45, 10
    %cond.v.i.47 = select i1 %cmp6.i.46, i8 48, i8 55
    %cond.i.48 = add i8 %cond.v.i.47, %conv4.i.45
    %incdec.ptr.i.49 = getelementptr inbounds i8, i8* %str.0.i.40, i16 -1
    store i8 %cond.i.48, i8* %incdec.ptr.i.49, align 1, !tbaa !4
    %tobool.i.50 = icmp eq i32 %div.i.42, 0
    br i1 %tobool.i.50, label %_ZN5Print11printNumberEmh.exit56, label %do.body.i.51

    _ZN5Print11printNumberEmh.exit56: ; preds = %do.body.i.51
    %incdec.ptr.i.49.lcssa = phi i8* [ %incdec.ptr.i.49, %do.body.i.51 ]
    %16 = bitcast %class.Print* %this to i16 (%class.Print*, i8*, i16)***
    %vtable.i.i.52 = load i16 (%class.Print*, i8*, i16)**, i16 (%class.Print*, i8*, i16)*** %16, align 1, !tbaa !1
    %vfn.i.i.53 = getelementptr inbounds i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vtable.i.i.52, i16 1
    %17 = load i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vfn.i.i.53, align 1
    %call.i.i.54 = call i16 @strlen(i8* %incdec.ptr.i.49.lcssa) #4
    %call2.i.i.55 = call i16 %17(%class.Print* %this, i8* %incdec.ptr.i.49.lcssa, i16 %call.i.i.54)
    call void @llvm.lifetime.end(i64 33, i8* %14) #1
    br label %return

    return: ; preds = %_ZN5Print11printNumberEmh.exit56, %_ZN5Print11printNumberEmh.exit37, %_ZN5Print11printNumberEmh.exit, %if.then
    %retval.0 = phi i16 [ %call, %if.then ], [ %add, %_ZN5Print11printNumberEmh.exit ], [ %call2.i.i.36, %_ZN5Print11printNumberEmh.exit37 ], [ %call2.i.i.55, %_ZN5Print11printNumberEmh.exit56 ]
    ret i16 %retval.0
    }

    define i16 @_ZN5Print5printEji(%class.Print* %this, i16 %n, i16 %base) #0 align 2 {
    entry:
    %buf.i.i = alloca [33 x i8], align 1
    %cmp.i = icmp eq i16 %base, 0
    br i1 %cmp.i, label %if.then.i, label %if.else.i

    if.then.i: ; preds = %entry
    %0 = bitcast %class.Print* %this to i16 (%class.Print*, i8)***
    %vtable.i = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %0, align 1, !tbaa !1
    %1 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i, align 1
    %conv.i = trunc i16 %n to i8
    %call.i = tail call i16 %1(%class.Print* %this, i8 zeroext %conv.i)
    br label %_ZN5Print5printEmi.exit

    if.else.i: ; preds = %entry
    %conv = zext i16 %n to i32
    %conv2.i = trunc i16 %base to i8
    %2 = getelementptr inbounds [33 x i8], [33 x i8]* %buf.i.i, i16 0, i16 0
    call void @llvm.lifetime.start(i64 33, i8* %2) #1
    %arrayidx.i.i = getelementptr inbounds [33 x i8], [33 x i8]* %buf.i.i, i16 0, i16 32
    store i8 0, i8* %arrayidx.i.i, align 1, !tbaa !4
    %cmp.i.i = icmp ult i8 %conv2.i, 2
    %conv2.mask.i = and i16 %base, 255
    %3 = zext i16 %conv2.mask.i to i32
    %conv2.i.i = select i1 %cmp.i.i, i32 10, i32 %3
    br label %do.body.i.i

    do.body.i.i: ; preds = %do.body.i.i, %if.else.i
    %str.0.i.i = phi i8* [ %incdec.ptr.i.i, %do.body.i.i ], [ %arrayidx.i.i, %if.else.i ]
    %n.addr.0.i.i = phi i32 [ %div.i.i, %do.body.i.i ], [ %conv, %if.else.i ]
    %div.i.i = udiv i32 %n.addr.0.i.i, %conv2.i.i
    %mul.i.i = mul i32 %div.i.i, %conv2.i.i
    %sub.i.i = sub i32 %n.addr.0.i.i, %mul.i.i
    %conv4.i.i = trunc i32 %sub.i.i to i8
    %cmp6.i.i = icmp slt i8 %conv4.i.i, 10
    %cond.v.i.i = select i1 %cmp6.i.i, i8 48, i8 55
    %cond.i.i = add i8 %cond.v.i.i, %conv4.i.i
    %incdec.ptr.i.i = getelementptr inbounds i8, i8* %str.0.i.i, i16 -1
    store i8 %cond.i.i, i8* %incdec.ptr.i.i, align 1, !tbaa !4
    %tobool.i.i = icmp eq i32 %div.i.i, 0
    br i1 %tobool.i.i, label %_ZN5Print11printNumberEmh.exit.i, label %do.body.i.i

    _ZN5Print11printNumberEmh.exit.i: ; preds = %do.body.i.i
    %incdec.ptr.i.i.lcssa = phi i8* [ %incdec.ptr.i.i, %do.body.i.i ]
    %4 = bitcast %class.Print* %this to i16 (%class.Print*, i8*, i16)***
    %vtable.i.i.i = load i16 (%class.Print*, i8*, i16)**, i16 (%class.Print*, i8*, i16)*** %4, align 1, !tbaa !1
    %vfn.i.i.i = getelementptr inbounds i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vtable.i.i.i, i16 1
    %5 = load i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vfn.i.i.i, align 1
    %call.i.i.i = call i16 @strlen(i8* %incdec.ptr.i.i.lcssa) #4
    %call2.i.i.i = call i16 %5(%class.Print* %this, i8* %incdec.ptr.i.i.lcssa, i16 %call.i.i.i)
    call void @llvm.lifetime.end(i64 33, i8* %2) #1
    br label %_ZN5Print5printEmi.exit

    _ZN5Print5printEmi.exit: ; preds = %if.then.i, %_ZN5Print11printNumberEmh.exit.i
    %retval.0.i = phi i16 [ %call.i, %if.then.i ], [ %call2.i.i.i, %_ZN5Print11printNumberEmh.exit.i ]
    ret i16 %retval.0.i
    }

    define i16 @_ZN5Print11printNumberEmh(%class.Print* %this, i32 %n, i8 zeroext %base) #0 align 2 {
    entry:
    %buf = alloca [33 x i8], align 1
    %0 = getelementptr inbounds [33 x i8], [33 x i8]* %buf, i16 0, i16 0
    call void @llvm.lifetime.start(i64 33, i8* %0) #1
    %arrayidx = getelementptr inbounds [33 x i8], [33 x i8]* %buf, i16 0, i16 32
    store i8 0, i8* %arrayidx, align 1, !tbaa !4
    %cmp = icmp ult i8 %base, 2
    %1 = zext i8 %base to i32
    %conv2 = select i1 %cmp, i32 10, i32 %1
    br label %do.body

    do.body: ; preds = %entry, %do.body
    %str.0 = phi i8* [ %incdec.ptr, %do.body ], [ %arrayidx, %entry ]
    %n.addr.0 = phi i32 [ %div, %do.body ], [ %n, %entry ]
    %div = udiv i32 %n.addr.0, %conv2
    %mul = mul i32 %div, %conv2
    %sub = sub i32 %n.addr.0, %mul
    %conv4 = trunc i32 %sub to i8
    %cmp6 = icmp slt i8 %conv4, 10
    %cond.v = select i1 %cmp6, i8 48, i8 55
    %cond = add i8 %cond.v, %conv4
    %incdec.ptr = getelementptr inbounds i8, i8* %str.0, i16 -1
    store i8 %cond, i8* %incdec.ptr, align 1, !tbaa !4
    %tobool = icmp eq i32 %div, 0
    br i1 %tobool, label %do.end, label %do.body

    do.end: ; preds = %do.body
    %incdec.ptr.lcssa = phi i8* [ %incdec.ptr, %do.body ]
    %2 = bitcast %class.Print* %this to i16 (%class.Print*, i8*, i16)***
    %vtable.i = load i16 (%class.Print*, i8*, i16)**, i16 (%class.Print*, i8*, i16)*** %2, align 1, !tbaa !1
    %vfn.i = getelementptr inbounds i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vtable.i, i16 1
    %3 = load i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vfn.i, align 1
    %call.i = call i16 @strlen(i8* %incdec.ptr.lcssa) #4
    %call2.i = call i16 %3(%class.Print* %this, i8* %incdec.ptr.lcssa, i16 %call.i)
    call void @llvm.lifetime.end(i64 33, i8* %0) #1
    ret i16 %call2.i
    }

    define i16 @_ZN5Print5printEdi(%class.Print* %this, double %n, i16 %digits) #0 align 2 {
    entry:
    %conv = trunc i16 %digits to i8
    %call = tail call i16 @_ZN5Print10printFloatEdh(%class.Print* %this, double %n, i8 zeroext %conv)
    ret i16 %call
    }

    define i16 @_ZN5Print10printFloatEdh(%class.Print* %this, double %number, i8 zeroext %digits) #0 align 2 {
    entry:
    %buf.i.i = alloca [33 x i8], align 1
    %call = tail call i16 @isnan(double %number) #5
    %tobool = icmp eq i16 %call, 0
    br i1 %tobool, label %if.end, label %if.then

    if.then: ; preds = %entry
    %0 = bitcast %class.Print* %this to i16 (%class.Print*, i8*, i16)***
    %vtable.i.i = load i16 (%class.Print*, i8*, i16)**, i16 (%class.Print*, i8*, i16)*** %0, align 1, !tbaa !1
    %vfn.i.i = getelementptr inbounds i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vtable.i.i, i16 1
    %1 = load i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vfn.i.i, align 1
    %call2.i.i = tail call i16 %1(%class.Print* %this, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i16 0, i16 0), i16 3)
    br label %cleanup

    if.end: ; preds = %entry
    %call3 = tail call i16 @isinf(double %number) #5
    %tobool4 = icmp eq i16 %call3, 0
    br i1 %tobool4, label %if.end.7, label %if.then.5

    if.then.5: ; preds = %if.end
    %2 = bitcast %class.Print* %this to i16 (%class.Print*, i8*, i16)***
    %vtable.i.i.65 = load i16 (%class.Print*, i8*, i16)**, i16 (%class.Print*, i8*, i16)*** %2, align 1, !tbaa !1
    %vfn.i.i.66 = getelementptr inbounds i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vtable.i.i.65, i16 1
    %3 = load i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vfn.i.i.66, align 1
    %call2.i.i.68 = tail call i16 %3(%class.Print* %this, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.1, i16 0, i16 0), i16 3)
    br label %cleanup

    if.end.7: ; preds = %if.end
    %cmp = fcmp ogt double %number, 0x41EFFFFFE0000000
    br i1 %cmp, label %if.then.8, label %if.end.10

    if.then.8: ; preds = %if.end.7
    %4 = bitcast %class.Print* %this to i16 (%class.Print*, i8*, i16)***
    %vtable.i.i.69 = load i16 (%class.Print*, i8*, i16)**, i16 (%class.Print*, i8*, i16)*** %4, align 1, !tbaa !1
    %vfn.i.i.70 = getelementptr inbounds i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vtable.i.i.69, i16 1
    %5 = load i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vfn.i.i.70, align 1
    %call2.i.i.72 = tail call i16 %5(%class.Print* %this, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.2, i16 0, i16 0), i16 3)
    br label %cleanup

    if.end.10: ; preds = %if.end.7
    %cmp11 = fcmp olt double %number, 0xC1EFFFFFE0000000
    br i1 %cmp11, label %if.then.12, label %if.end.14

    if.then.12: ; preds = %if.end.10
    %6 = bitcast %class.Print* %this to i16 (%class.Print*, i8*, i16)***
    %vtable.i.i.73 = load i16 (%class.Print*, i8*, i16)**, i16 (%class.Print*, i8*, i16)*** %6, align 1, !tbaa !1
    %vfn.i.i.74 = getelementptr inbounds i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vtable.i.i.73, i16 1
    %7 = load i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vfn.i.i.74, align 1
    %call2.i.i.76 = tail call i16 %7(%class.Print* %this, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.2, i16 0, i16 0), i16 3)
    br label %cleanup

    if.end.14: ; preds = %if.end.10
    %cmp15 = fcmp olt double %number, 0.000000e+00
    br i1 %cmp15, label %if.then.16, label %if.end.18

    if.then.16: ; preds = %if.end.14
    %8 = bitcast %class.Print* %this to i16 (%class.Print*, i8)***
    %vtable.i = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %8, align 1, !tbaa !1
    %9 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i, align 1
    %call.i = tail call i16 %9(%class.Print* %this, i8 zeroext 45)
    %sub = fsub double -0.000000e+00, %number
    br label %if.end.18

    if.end.18: ; preds = %if.then.16, %if.end.14
    %n.0 = phi i16 [ %call.i, %if.then.16 ], [ 0, %if.end.14 ]
    %number.addr.0 = phi double [ %sub, %if.then.16 ], [ %number, %if.end.14 ]
    %cmp20.86 = icmp eq i8 %digits, 0
    br i1 %cmp20.86, label %for.cond.cleanup, label %for.body.preheader

    for.body.preheader: ; preds = %if.end.18
    br label %for.body

    for.cond.cleanup.loopexit: ; preds = %for.body
    %div.lcssa = phi double [ %div, %for.body ]
    br label %for.cond.cleanup

    for.cond.cleanup: ; preds = %for.cond.cleanup.loopexit, %if.end.18
    %rounding.0.lcssa = phi double [ 5.000000e-01, %if.end.18 ], [ %div.lcssa, %for.cond.cleanup.loopexit ]
    %add21 = fadd double %number.addr.0, %rounding.0.lcssa
    %conv22 = fptoui double %add21 to i32
    %conv23 = uitofp i32 %conv22 to double
    %10 = getelementptr inbounds [33 x i8], [33 x i8]* %buf.i.i, i16 0, i16 0
    call void @llvm.lifetime.start(i64 33, i8* %10) #1
    %arrayidx.i.i = getelementptr inbounds [33 x i8], [33 x i8]* %buf.i.i, i16 0, i16 32
    store i8 0, i8* %arrayidx.i.i, align 1, !tbaa !4
    br label %do.body.i.i

    do.body.i.i: ; preds = %do.body.i.i, %for.cond.cleanup
    %str.0.i.i = phi i8* [ %incdec.ptr.i.i, %do.body.i.i ], [ %arrayidx.i.i, %for.cond.cleanup ]
    %n.addr.0.i.i = phi i32 [ %div.i.i, %do.body.i.i ], [ %conv22, %for.cond.cleanup ]
    %div.i.i = udiv i32 %n.addr.0.i.i, 10
    %11 = mul i32 %div.i.i, -10
    %sub.i.i = add i32 %11, %n.addr.0.i.i
    %conv4.i.i = trunc i32 %sub.i.i to i8
    %cmp6.i.i = icmp slt i8 %conv4.i.i, 10
    %cond.v.i.i = select i1 %cmp6.i.i, i8 48, i8 55
    %cond.i.i = add i8 %cond.v.i.i, %conv4.i.i
    %incdec.ptr.i.i = getelementptr inbounds i8, i8* %str.0.i.i, i16 -1
    store i8 %cond.i.i, i8* %incdec.ptr.i.i, align 1, !tbaa !4
    %12 = icmp ult i32 %n.addr.0.i.i, 10
    br i1 %12, label %_ZN5Print5printEmi.exit, label %do.body.i.i

    _ZN5Print5printEmi.exit: ; preds = %do.body.i.i
    %incdec.ptr.i.i.lcssa = phi i8* [ %incdec.ptr.i.i, %do.body.i.i ]
    %13 = bitcast %class.Print* %this to i16 (%class.Print*, i8*, i16)***
    %vtable.i.i.i = load i16 (%class.Print*, i8*, i16)**, i16 (%class.Print*, i8*, i16)*** %13, align 1, !tbaa !1
    %vfn.i.i.i = getelementptr inbounds i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vtable.i.i.i, i16 1
    %14 = load i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vfn.i.i.i, align 1
    %call.i.i.i = call i16 @strlen(i8* %incdec.ptr.i.i.lcssa) #4
    %call2.i.i.i = call i16 %14(%class.Print* %this, i8* %incdec.ptr.i.i.lcssa, i16 %call.i.i.i)
    call void @llvm.lifetime.end(i64 33, i8* %10) #1
    %add26 = add i16 %call2.i.i.i, %n.0
    br i1 %cmp20.86, label %cleanup, label %while.body.lr.ph

    for.body: ; preds = %for.body.preheader, %for.body
    %i.088 = phi i8 [ %inc, %for.body ], [ 0, %for.body.preheader ]
    %rounding.087 = phi double [ %div, %for.body ], [ 5.000000e-01, %for.body.preheader ]
    %div = fdiv double %rounding.087, 1.000000e+01
    %inc = add nuw i8 %i.088, 1
    %exitcond = icmp eq i8 %inc, %digits
    br i1 %exitcond, label %for.cond.cleanup.loopexit, label %for.body

    while.body.lr.ph: ; preds = %_ZN5Print5printEmi.exit
    %sub24 = fsub double %add21, %conv23
    %vtable.i.i.77 = load i16 (%class.Print*, i8*, i16)**, i16 (%class.Print*, i8*, i16)*** %13, align 1, !tbaa !1
    %vfn.i.i.78 = getelementptr inbounds i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vtable.i.i.77, i16 1
    %15 = load i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vfn.i.i.78, align 1
    %call2.i.i.80 = call i16 %15(%class.Print* %this, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.3, i16 0, i16 0), i16 1)
    %add31 = add i16 %call2.i.i.80, %add26
    br label %while.body

    while.body: ; preds = %while.body.lr.ph, %while.body
    %remainder.085 = phi double [ %sub24, %while.body.lr.ph ], [ %sub39, %while.body ]
    %n.184 = phi i16 [ %add31, %while.body.lr.ph ], [ %add37, %while.body ]
    %digits.addr.083 = phi i8 [ %digits, %while.body.lr.ph ], [ %dec, %while.body ]
    %dec = add i8 %digits.addr.083, -1
    %mul = fmul double %remainder.085, 1.000000e+01
    %conv35 = fptosi double %mul to i16
    %conv.i = sext i16 %conv35 to i32
    %call.i.81 = call i16 @_ZN5Print5printEli(%class.Print* %this, i32 %conv.i, i16 10)
    %add37 = add i16 %call.i.81, %n.184
    %conv38 = sitofp i16 %conv35 to double
    %sub39 = fsub double %mul, %conv38
    %cmp34 = icmp eq i8 %dec, 0
    br i1 %cmp34, label %cleanup.loopexit, label %while.body

    cleanup.loopexit: ; preds = %while.body
    %add37.lcssa = phi i16 [ %add37, %while.body ]
    br label %cleanup

    cleanup: ; preds = %cleanup.loopexit, %_ZN5Print5printEmi.exit, %if.then.12, %if.then.8, %if.then.5, %if.then
    %retval.0 = phi i16 [ %call2.i.i, %if.then ], [ %call2.i.i.68, %if.then.5 ], [ %call2.i.i.72, %if.then.8 ], [ %call2.i.i.76, %if.then.12 ], [ %add26, %_ZN5Print5printEmi.exit ], [ %add37.lcssa, %cleanup.loopexit ]
    ret i16 %retval.0
    }

    define i16 @_ZN5Print7printlnEPK19__FlashStringHelper(%class.Print* %this, %class.__FlashStringHelper* %ifsh) #0 align 2 {
    entry:
    %0 = ptrtoint %class.__FlashStringHelper* %ifsh to i16
    %1 = tail call i8 asm sideeffect "lpm\0A\09mov $0, r0\0A\09", "=r,z,~{r0}"(i16 %0) #1, !srcloc !6
    %cmp.9.i = icmp eq i8 %1, 0
    br i1 %cmp.9.i, label %entry._ZN5Print5printEPK19__FlashStringHelper.exit_crit_edge, label %cleanup.thread.lr.ph.i

    entry._ZN5Print5printEPK19__FlashStringHelper.exit_crit_edge: ; preds = %entry
    %.pre = bitcast %class.Print* %this to i16 (%class.Print*, i8)***
    br label %_ZN5Print5printEPK19__FlashStringHelper.exit

    cleanup.thread.lr.ph.i: ; preds = %entry
    %2 = bitcast %class.__FlashStringHelper* %ifsh to i8*
    %3 = bitcast %class.Print* %this to i16 (%class.Print*, i8)***
    br label %cleanup.thread.i

    cleanup.thread.i: ; preds = %cleanup.thread.i, %cleanup.thread.lr.ph.i
    %4 = phi i8 [ %1, %cleanup.thread.lr.ph.i ], [ %7, %cleanup.thread.i ]
    %p.011.i = phi i8* [ %2, %cleanup.thread.lr.ph.i ], [ %incdec.ptr.i, %cleanup.thread.i ]
    %n.010.i = phi i16 [ 0, %cleanup.thread.lr.ph.i ], [ %add.i, %cleanup.thread.i ]
    %incdec.ptr.i = getelementptr inbounds i8, i8* %p.011.i, i16 1
    %vtable.i = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %3, align 1, !tbaa !1
    %5 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i, align 1
    %call.i = tail call i16 %5(%class.Print* %this, i8 zeroext %4)
    %add.i = add i16 %call.i, %n.010.i
    %6 = ptrtoint i8* %incdec.ptr.i to i16
    %7 = tail call i8 asm sideeffect "lpm\0A\09mov $0, r0\0A\09", "=r,z,~{r0}"(i16 %6) #1, !srcloc !6
    %cmp.i = icmp eq i8 %7, 0
    br i1 %cmp.i, label %_ZN5Print5printEPK19__FlashStringHelper.exit.loopexit, label %cleanup.thread.i

    _ZN5Print5printEPK19__FlashStringHelper.exit.loopexit: ; preds = %cleanup.thread.i
    %add.i.lcssa = phi i16 [ %add.i, %cleanup.thread.i ]
    br label %_ZN5Print5printEPK19__FlashStringHelper.exit

    _ZN5Print5printEPK19__FlashStringHelper.exit: ; preds = %_ZN5Print5printEPK19__FlashStringHelper.exit.loopexit, %entry._ZN5Print5printEPK19__FlashStringHelper.exit_crit_edge
    %.pre-phi = phi i16 (%class.Print*, i8)*** [ %.pre, %entry._ZN5Print5printEPK19__FlashStringHelper.exit_crit_edge ], [ %3, %_ZN5Print5printEPK19__FlashStringHelper.exit.loopexit ]
    %n.0.lcssa.i = phi i16 [ 0, %entry._ZN5Print5printEPK19__FlashStringHelper.exit_crit_edge ], [ %add.i.lcssa, %_ZN5Print5printEPK19__FlashStringHelper.exit.loopexit ]
    %vtable.i.i = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %.pre-phi, align 1, !tbaa !1
    %8 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i.i, align 1
    %call.i.i = tail call i16 %8(%class.Print* %this, i8 zeroext 13)
    %vtable.i.5.i = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %.pre-phi, align 1, !tbaa !1
    %9 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i.5.i, align 1
    %call.i.6.i = tail call i16 %9(%class.Print* %this, i8 zeroext 10)
    %add.i.5 = add i16 %call.i.i, %n.0.lcssa.i
    %add = add i16 %add.i.5, %call.i.6.i
    ret i16 %add
    }

    define i16 @_ZN5Print7printlnEv(%class.Print* %this) #0 align 2 {
    entry:
    %0 = bitcast %class.Print* %this to i16 (%class.Print*, i8)***
    %vtable.i = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %0, align 1, !tbaa !1
    %1 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i, align 1
    %call.i = tail call i16 %1(%class.Print* %this, i8 zeroext 13)
    %vtable.i.5 = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %0, align 1, !tbaa !1
    %2 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i.5, align 1
    %call.i.6 = tail call i16 %2(%class.Print* %this, i8 zeroext 10)
    %add = add i16 %call.i.6, %call.i
    ret i16 %add
    }

    define i16 @_ZN5Print5printERK9Printable(%class.Print* %this, %class.Printable* dereferenceable(2) %x) #0 align 2 {
    entry:
    %0 = bitcast %class.Printable* %x to i16 (%class.Printable*, %class.Print*)***
    %vtable = load i16 (%class.Printable*, %class.Print*)**, i16 (%class.Printable*, %class.Print*)*** %0, align 1, !tbaa !1
    %1 = load i16 (%class.Printable*, %class.Print*)*, i16 (%class.Printable*, %class.Print*)** %vtable, align 1
    %call = tail call i16 %1(%class.Printable* nonnull %x, %class.Print* dereferenceable(4) %this)
    ret i16 %call
    }

    define i16 @_ZN5Print7printlnERK6String(%class.Print* %this, %class.String* nocapture readonly dereferenceable(6) %s) #0 align 2 {
    entry:
    %buffer.i.i = getelementptr inbounds %class.String, %class.String* %s, i16 0, i32 0
    %0 = load i8*, i8** %buffer.i.i, align 2, !tbaa !7
    %len.i.i = getelementptr inbounds %class.String, %class.String* %s, i16 0, i32 2
    %1 = load i16, i16* %len.i.i, align 2, !tbaa !11
    %2 = bitcast %class.Print* %this to i16 (%class.Print*, i8*, i16)***
    %vtable.i.i = load i16 (%class.Print*, i8*, i16)**, i16 (%class.Print*, i8*, i16)*** %2, align 1, !tbaa !1
    %vfn.i.i = getelementptr inbounds i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vtable.i.i, i16 1
    %3 = load i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vfn.i.i, align 1
    %call.i.i = tail call i16 %3(%class.Print* %this, i8* %0, i16 %1)
    %4 = bitcast %class.Print* %this to i16 (%class.Print*, i8)***
    %vtable.i.i.5 = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %4, align 1, !tbaa !1
    %5 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i.i.5, align 1
    %call.i.i.6 = tail call i16 %5(%class.Print* %this, i8 zeroext 13)
    %vtable.i.5.i = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %4, align 1, !tbaa !1
    %6 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i.5.i, align 1
    %call.i.6.i = tail call i16 %6(%class.Print* %this, i8 zeroext 10)
    %add.i = add i16 %call.i.i.6, %call.i.i
    %add = add i16 %add.i, %call.i.6.i
    ret i16 %add
    }

    define i16 @_ZN5Print7printlnEPKc(%class.Print* %this, i8* %c) #0 align 2 {
    entry:
    %cmp.i.i = icmp eq i8* %c, null
    br i1 %cmp.i.i, label %_ZN5Print5printEPKc.exit, label %if.end.i.i

    if.end.i.i: ; preds = %entry
    %0 = bitcast %class.Print* %this to i16 (%class.Print*, i8*, i16)***
    %vtable.i.i = load i16 (%class.Print*, i8*, i16)**, i16 (%class.Print*, i8*, i16)*** %0, align 1, !tbaa !1
    %vfn.i.i = getelementptr inbounds i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vtable.i.i, i16 1
    %1 = load i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vfn.i.i, align 1
    %call.i.i = tail call i16 @strlen(i8* %c) #4
    %call2.i.i = tail call i16 %1(%class.Print* %this, i8* %c, i16 %call.i.i)
    br label %_ZN5Print5printEPKc.exit

    _ZN5Print5printEPKc.exit: ; preds = %entry, %if.end.i.i
    %retval.0.i.i = phi i16 [ %call2.i.i, %if.end.i.i ], [ 0, %entry ]
    %2 = bitcast %class.Print* %this to i16 (%class.Print*, i8)***
    %vtable.i.i.5 = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %2, align 1, !tbaa !1
    %3 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i.i.5, align 1
    %call.i.i.6 = tail call i16 %3(%class.Print* %this, i8 zeroext 13)
    %vtable.i.5.i = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %2, align 1, !tbaa !1
    %4 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i.5.i, align 1
    %call.i.6.i = tail call i16 %4(%class.Print* %this, i8 zeroext 10)
    %add.i = add i16 %call.i.i.6, %retval.0.i.i
    %add = add i16 %add.i, %call.i.6.i
    ret i16 %add
    }

    define i16 @_ZN5Print7printlnEc(%class.Print* %this, i8 signext %c) #0 align 2 {
    entry:
    %0 = bitcast %class.Print* %this to i16 (%class.Print*, i8)***
    %vtable.i = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %0, align 1, !tbaa !1
    %1 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i, align 1
    %call.i = tail call i16 %1(%class.Print* %this, i8 zeroext %c)
    %vtable.i.i = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %0, align 1, !tbaa !1
    %2 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i.i, align 1
    %call.i.i = tail call i16 %2(%class.Print* %this, i8 zeroext 13)
    %vtable.i.5.i = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %0, align 1, !tbaa !1
    %3 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i.5.i, align 1
    %call.i.6.i = tail call i16 %3(%class.Print* %this, i8 zeroext 10)
    %add.i = add i16 %call.i.i, %call.i
    %add = add i16 %add.i, %call.i.6.i
    ret i16 %add
    }

    define i16 @_ZN5Print7printlnEhi(%class.Print* %this, i8 zeroext %b, i16 %base) #0 align 2 {
    entry:
    %buf.i.i.i = alloca [33 x i8], align 1
    %cmp.i.i = icmp eq i16 %base, 0
    br i1 %cmp.i.i, label %if.then.i.i, label %if.else.i.i

    if.then.i.i: ; preds = %entry
    %0 = bitcast %class.Print* %this to i16 (%class.Print*, i8)***
    %vtable.i.i = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %0, align 1, !tbaa !1
    %1 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i.i, align 1
    %call.i.i = tail call i16 %1(%class.Print* %this, i8 zeroext %b)
    br label %_ZN5Print5printEhi.exit

    if.else.i.i: ; preds = %entry
    %conv.i = zext i8 %b to i32
    %conv2.i.i = trunc i16 %base to i8
    %2 = getelementptr inbounds [33 x i8], [33 x i8]* %buf.i.i.i, i16 0, i16 0
    call void @llvm.lifetime.start(i64 33, i8* %2) #1
    %arrayidx.i.i.i = getelementptr inbounds [33 x i8], [33 x i8]* %buf.i.i.i, i16 0, i16 32
    store i8 0, i8* %arrayidx.i.i.i, align 1, !tbaa !4
    %cmp.i.i.i = icmp ult i8 %conv2.i.i, 2
    %conv2.mask.i.i = and i16 %base, 255
    %3 = zext i16 %conv2.mask.i.i to i32
    %conv2.i.i.i = select i1 %cmp.i.i.i, i32 10, i32 %3
    br label %do.body.i.i.i

    do.body.i.i.i: ; preds = %do.body.i.i.i, %if.else.i.i
    %str.0.i.i.i = phi i8* [ %incdec.ptr.i.i.i, %do.body.i.i.i ], [ %arrayidx.i.i.i, %if.else.i.i ]
    %n.addr.0.i.i.i = phi i32 [ %div.i.i.i, %do.body.i.i.i ], [ %conv.i, %if.else.i.i ]
    %div.i.i.i = udiv i32 %n.addr.0.i.i.i, %conv2.i.i.i
    %mul.i.i.i = mul i32 %div.i.i.i, %conv2.i.i.i
    %sub.i.i.i = sub i32 %n.addr.0.i.i.i, %mul.i.i.i
    %conv4.i.i.i = trunc i32 %sub.i.i.i to i8
    %cmp6.i.i.i = icmp slt i8 %conv4.i.i.i, 10
    %cond.v.i.i.i = select i1 %cmp6.i.i.i, i8 48, i8 55
    %cond.i.i.i = add i8 %cond.v.i.i.i, %conv4.i.i.i
    %incdec.ptr.i.i.i = getelementptr inbounds i8, i8* %str.0.i.i.i, i16 -1
    store i8 %cond.i.i.i, i8* %incdec.ptr.i.i.i, align 1, !tbaa !4
    %tobool.i.i.i = icmp eq i32 %div.i.i.i, 0
    br i1 %tobool.i.i.i, label %_ZN5Print11printNumberEmh.exit.i.i, label %do.body.i.i.i

    _ZN5Print11printNumberEmh.exit.i.i: ; preds = %do.body.i.i.i
    %incdec.ptr.i.i.i.lcssa = phi i8* [ %incdec.ptr.i.i.i, %do.body.i.i.i ]
    %4 = bitcast %class.Print* %this to i16 (%class.Print*, i8*, i16)***
    %vtable.i.i.i.i = load i16 (%class.Print*, i8*, i16)**, i16 (%class.Print*, i8*, i16)*** %4, align 1, !tbaa !1
    %vfn.i.i.i.i = getelementptr inbounds i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vtable.i.i.i.i, i16 1
    %5 = load i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vfn.i.i.i.i, align 1
    %call.i.i.i.i = call i16 @strlen(i8* %incdec.ptr.i.i.i.lcssa) #4
    %call2.i.i.i.i = call i16 %5(%class.Print* %this, i8* %incdec.ptr.i.i.i.lcssa, i16 %call.i.i.i.i)
    call void @llvm.lifetime.end(i64 33, i8* %2) #1
    %.pre = bitcast %class.Print* %this to i16 (%class.Print*, i8)***
    br label %_ZN5Print5printEhi.exit

    _ZN5Print5printEhi.exit: ; preds = %if.then.i.i, %_ZN5Print11printNumberEmh.exit.i.i
    %.pre-phi = phi i16 (%class.Print*, i8)*** [ %0, %if.then.i.i ], [ %.pre, %_ZN5Print11printNumberEmh.exit.i.i ]
    %retval.0.i.i = phi i16 [ %call.i.i, %if.then.i.i ], [ %call2.i.i.i.i, %_ZN5Print11printNumberEmh.exit.i.i ]
    %vtable.i.i.5 = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %.pre-phi, align 1, !tbaa !1
    %6 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i.i.5, align 1
    %call.i.i.6 = call i16 %6(%class.Print* %this, i8 zeroext 13)
    %vtable.i.5.i = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %.pre-phi, align 1, !tbaa !1
    %7 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i.5.i, align 1
    %call.i.6.i = call i16 %7(%class.Print* %this, i8 zeroext 10)
    %add.i = add i16 %call.i.i.6, %retval.0.i.i
    %add = add i16 %add.i, %call.i.6.i
    ret i16 %add
    }

    define i16 @_ZN5Print7printlnEii(%class.Print* %this, i16 %num, i16 %base) #0 align 2 {
    entry:
    %conv.i = sext i16 %num to i32
    %call.i = tail call i16 @_ZN5Print5printEli(%class.Print* %this, i32 %conv.i, i16 %base)
    %0 = bitcast %class.Print* %this to i16 (%class.Print*, i8)***
    %vtable.i.i = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %0, align 1, !tbaa !1
    %1 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i.i, align 1
    %call.i.i = tail call i16 %1(%class.Print* %this, i8 zeroext 13)
    %vtable.i.5.i = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %0, align 1, !tbaa !1
    %2 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i.5.i, align 1
    %call.i.6.i = tail call i16 %2(%class.Print* %this, i8 zeroext 10)
    %add.i = add i16 %call.i.i, %call.i
    %add = add i16 %add.i, %call.i.6.i
    ret i16 %add
    }

    define i16 @_ZN5Print7printlnEji(%class.Print* %this, i16 %num, i16 %base) #0 align 2 {
    entry:
    %buf.i.i.i = alloca [33 x i8], align 1
    %cmp.i.i = icmp eq i16 %base, 0
    br i1 %cmp.i.i, label %if.then.i.i, label %if.else.i.i

    if.then.i.i: ; preds = %entry
    %0 = bitcast %class.Print* %this to i16 (%class.Print*, i8)***
    %vtable.i.i = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %0, align 1, !tbaa !1
    %1 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i.i, align 1
    %conv.i.i = trunc i16 %num to i8
    %call.i.i = tail call i16 %1(%class.Print* %this, i8 zeroext %conv.i.i)
    br label %_ZN5Print5printEji.exit

    if.else.i.i: ; preds = %entry
    %conv.i = zext i16 %num to i32
    %conv2.i.i = trunc i16 %base to i8
    %2 = getelementptr inbounds [33 x i8], [33 x i8]* %buf.i.i.i, i16 0, i16 0
    call void @llvm.lifetime.start(i64 33, i8* %2) #1
    %arrayidx.i.i.i = getelementptr inbounds [33 x i8], [33 x i8]* %buf.i.i.i, i16 0, i16 32
    store i8 0, i8* %arrayidx.i.i.i, align 1, !tbaa !4
    %cmp.i.i.i = icmp ult i8 %conv2.i.i, 2
    %conv2.mask.i.i = and i16 %base, 255
    %3 = zext i16 %conv2.mask.i.i to i32
    %conv2.i.i.i = select i1 %cmp.i.i.i, i32 10, i32 %3
    br label %do.body.i.i.i

    do.body.i.i.i: ; preds = %do.body.i.i.i, %if.else.i.i
    %str.0.i.i.i = phi i8* [ %incdec.ptr.i.i.i, %do.body.i.i.i ], [ %arrayidx.i.i.i, %if.else.i.i ]
    %n.addr.0.i.i.i = phi i32 [ %div.i.i.i, %do.body.i.i.i ], [ %conv.i, %if.else.i.i ]
    %div.i.i.i = udiv i32 %n.addr.0.i.i.i, %conv2.i.i.i
    %mul.i.i.i = mul i32 %div.i.i.i, %conv2.i.i.i
    %sub.i.i.i = sub i32 %n.addr.0.i.i.i, %mul.i.i.i
    %conv4.i.i.i = trunc i32 %sub.i.i.i to i8
    %cmp6.i.i.i = icmp slt i8 %conv4.i.i.i, 10
    %cond.v.i.i.i = select i1 %cmp6.i.i.i, i8 48, i8 55
    %cond.i.i.i = add i8 %cond.v.i.i.i, %conv4.i.i.i
    %incdec.ptr.i.i.i = getelementptr inbounds i8, i8* %str.0.i.i.i, i16 -1
    store i8 %cond.i.i.i, i8* %incdec.ptr.i.i.i, align 1, !tbaa !4
    %tobool.i.i.i = icmp eq i32 %div.i.i.i, 0
    br i1 %tobool.i.i.i, label %_ZN5Print11printNumberEmh.exit.i.i, label %do.body.i.i.i

    _ZN5Print11printNumberEmh.exit.i.i: ; preds = %do.body.i.i.i
    %incdec.ptr.i.i.i.lcssa = phi i8* [ %incdec.ptr.i.i.i, %do.body.i.i.i ]
    %4 = bitcast %class.Print* %this to i16 (%class.Print*, i8*, i16)***
    %vtable.i.i.i.i = load i16 (%class.Print*, i8*, i16)**, i16 (%class.Print*, i8*, i16)*** %4, align 1, !tbaa !1
    %vfn.i.i.i.i = getelementptr inbounds i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vtable.i.i.i.i, i16 1
    %5 = load i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vfn.i.i.i.i, align 1
    %call.i.i.i.i = call i16 @strlen(i8* %incdec.ptr.i.i.i.lcssa) #4
    %call2.i.i.i.i = call i16 %5(%class.Print* %this, i8* %incdec.ptr.i.i.i.lcssa, i16 %call.i.i.i.i)
    call void @llvm.lifetime.end(i64 33, i8* %2) #1
    %.pre = bitcast %class.Print* %this to i16 (%class.Print*, i8)***
    br label %_ZN5Print5printEji.exit

    _ZN5Print5printEji.exit: ; preds = %if.then.i.i, %_ZN5Print11printNumberEmh.exit.i.i
    %.pre-phi = phi i16 (%class.Print*, i8)*** [ %0, %if.then.i.i ], [ %.pre, %_ZN5Print11printNumberEmh.exit.i.i ]
    %retval.0.i.i = phi i16 [ %call.i.i, %if.then.i.i ], [ %call2.i.i.i.i, %_ZN5Print11printNumberEmh.exit.i.i ]
    %vtable.i.i.5 = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %.pre-phi, align 1, !tbaa !1
    %6 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i.i.5, align 1
    %call.i.i.6 = call i16 %6(%class.Print* %this, i8 zeroext 13)
    %vtable.i.5.i = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %.pre-phi, align 1, !tbaa !1
    %7 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i.5.i, align 1
    %call.i.6.i = call i16 %7(%class.Print* %this, i8 zeroext 10)
    %add.i = add i16 %call.i.i.6, %retval.0.i.i
    %add = add i16 %add.i, %call.i.6.i
    ret i16 %add
    }

    define i16 @_ZN5Print7printlnEli(%class.Print* %this, i32 %num, i16 %base) #0 align 2 {
    entry:
    %call = tail call i16 @_ZN5Print5printEli(%class.Print* %this, i32 %num, i16 %base)
    %0 = bitcast %class.Print* %this to i16 (%class.Print*, i8)***
    %vtable.i.i = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %0, align 1, !tbaa !1
    %1 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i.i, align 1
    %call.i.i = tail call i16 %1(%class.Print* %this, i8 zeroext 13)
    %vtable.i.5.i = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %0, align 1, !tbaa !1
    %2 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i.5.i, align 1
    %call.i.6.i = tail call i16 %2(%class.Print* %this, i8 zeroext 10)
    %add.i = add i16 %call.i.i, %call
    %add = add i16 %add.i, %call.i.6.i
    ret i16 %add
    }

    define i16 @_ZN5Print7printlnEmi(%class.Print* %this, i32 %num, i16 %base) #0 align 2 {
    entry:
    %buf.i.i = alloca [33 x i8], align 1
    %cmp.i = icmp eq i16 %base, 0
    br i1 %cmp.i, label %if.then.i, label %if.else.i

    if.then.i: ; preds = %entry
    %0 = bitcast %class.Print* %this to i16 (%class.Print*, i8)***
    %vtable.i = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %0, align 1, !tbaa !1
    %1 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i, align 1
    %conv.i = trunc i32 %num to i8
    %call.i = tail call i16 %1(%class.Print* %this, i8 zeroext %conv.i)
    br label %_ZN5Print5printEmi.exit

    if.else.i: ; preds = %entry
    %conv2.i = trunc i16 %base to i8
    %2 = getelementptr inbounds [33 x i8], [33 x i8]* %buf.i.i, i16 0, i16 0
    call void @llvm.lifetime.start(i64 33, i8* %2) #1
    %arrayidx.i.i = getelementptr inbounds [33 x i8], [33 x i8]* %buf.i.i, i16 0, i16 32
    store i8 0, i8* %arrayidx.i.i, align 1, !tbaa !4
    %cmp.i.i = icmp ult i8 %conv2.i, 2
    %conv2.mask.i = and i16 %base, 255
    %3 = zext i16 %conv2.mask.i to i32
    %conv2.i.i = select i1 %cmp.i.i, i32 10, i32 %3
    br label %do.body.i.i

    do.body.i.i: ; preds = %do.body.i.i, %if.else.i
    %str.0.i.i = phi i8* [ %incdec.ptr.i.i, %do.body.i.i ], [ %arrayidx.i.i, %if.else.i ]
    %n.addr.0.i.i = phi i32 [ %div.i.i, %do.body.i.i ], [ %num, %if.else.i ]
    %div.i.i = udiv i32 %n.addr.0.i.i, %conv2.i.i
    %mul.i.i = mul i32 %div.i.i, %conv2.i.i
    %sub.i.i = sub i32 %n.addr.0.i.i, %mul.i.i
    %conv4.i.i = trunc i32 %sub.i.i to i8
    %cmp6.i.i = icmp slt i8 %conv4.i.i, 10
    %cond.v.i.i = select i1 %cmp6.i.i, i8 48, i8 55
    %cond.i.i = add i8 %cond.v.i.i, %conv4.i.i
    %incdec.ptr.i.i = getelementptr inbounds i8, i8* %str.0.i.i, i16 -1
    store i8 %cond.i.i, i8* %incdec.ptr.i.i, align 1, !tbaa !4
    %tobool.i.i = icmp eq i32 %div.i.i, 0
    br i1 %tobool.i.i, label %_ZN5Print11printNumberEmh.exit.i, label %do.body.i.i

    _ZN5Print11printNumberEmh.exit.i: ; preds = %do.body.i.i
    %incdec.ptr.i.i.lcssa = phi i8* [ %incdec.ptr.i.i, %do.body.i.i ]
    %4 = bitcast %class.Print* %this to i16 (%class.Print*, i8*, i16)***
    %vtable.i.i.i = load i16 (%class.Print*, i8*, i16)**, i16 (%class.Print*, i8*, i16)*** %4, align 1, !tbaa !1
    %vfn.i.i.i = getelementptr inbounds i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vtable.i.i.i, i16 1
    %5 = load i16 (%class.Print*, i8*, i16)*, i16 (%class.Print*, i8*, i16)** %vfn.i.i.i, align 1
    %call.i.i.i = call i16 @strlen(i8* %incdec.ptr.i.i.lcssa) #4
    %call2.i.i.i = call i16 %5(%class.Print* %this, i8* %incdec.ptr.i.i.lcssa, i16 %call.i.i.i)
    call void @llvm.lifetime.end(i64 33, i8* %2) #1
    %.pre = bitcast %class.Print* %this to i16 (%class.Print*, i8)***
    br label %_ZN5Print5printEmi.exit

    _ZN5Print5printEmi.exit: ; preds = %if.then.i, %_ZN5Print11printNumberEmh.exit.i
    %.pre-phi = phi i16 (%class.Print*, i8)*** [ %0, %if.then.i ], [ %.pre, %_ZN5Print11printNumberEmh.exit.i ]
    %retval.0.i = phi i16 [ %call.i, %if.then.i ], [ %call2.i.i.i, %_ZN5Print11printNumberEmh.exit.i ]
    %vtable.i.i = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %.pre-phi, align 1, !tbaa !1
    %6 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i.i, align 1
    %call.i.i = call i16 %6(%class.Print* %this, i8 zeroext 13)
    %vtable.i.5.i = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %.pre-phi, align 1, !tbaa !1
    %7 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i.5.i, align 1
    %call.i.6.i = call i16 %7(%class.Print* %this, i8 zeroext 10)
    %add.i = add i16 %call.i.i, %retval.0.i
    %add = add i16 %add.i, %call.i.6.i
    ret i16 %add
    }

    define i16 @_ZN5Print7printlnEdi(%class.Print* %this, double %num, i16 %digits) #0 align 2 {
    entry:
    %conv.i = trunc i16 %digits to i8
    %call.i = tail call i16 @_ZN5Print10printFloatEdh(%class.Print* %this, double %num, i8 zeroext %conv.i)
    %0 = bitcast %class.Print* %this to i16 (%class.Print*, i8)***
    %vtable.i.i = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %0, align 1, !tbaa !1
    %1 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i.i, align 1
    %call.i.i = tail call i16 %1(%class.Print* %this, i8 zeroext 13)
    %vtable.i.5.i = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %0, align 1, !tbaa !1
    %2 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i.5.i, align 1
    %call.i.6.i = tail call i16 %2(%class.Print* %this, i8 zeroext 10)
    %add.i = add i16 %call.i.i, %call.i
    %add = add i16 %add.i, %call.i.6.i
    ret i16 %add
    }

    define i16 @_ZN5Print7printlnERK9Printable(%class.Print* %this, %class.Printable* dereferenceable(2) %x) #0 align 2 {
    entry:
    %0 = bitcast %class.Printable* %x to i16 (%class.Printable*, %class.Print*)***
    %vtable.i = load i16 (%class.Printable*, %class.Print*)**, i16 (%class.Printable*, %class.Print*)*** %0, align 1, !tbaa !1
    %1 = load i16 (%class.Printable*, %class.Print*)*, i16 (%class.Printable*, %class.Print*)** %vtable.i, align 1
    %call.i = tail call i16 %1(%class.Printable* nonnull %x, %class.Print* dereferenceable(4) %this)
    %2 = bitcast %class.Print* %this to i16 (%class.Print*, i8)***
    %vtable.i.i = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %2, align 1, !tbaa !1
    %3 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i.i, align 1
    %call.i.i = tail call i16 %3(%class.Print* %this, i8 zeroext 13)
    %vtable.i.5.i = load i16 (%class.Print*, i8)**, i16 (%class.Print*, i8)*** %2, align 1, !tbaa !1
    %4 = load i16 (%class.Print*, i8)*, i16 (%class.Print*, i8)** %vtable.i.5.i, align 1
    %call.i.6.i = tail call i16 %4(%class.Print* %this, i8 zeroext 10)
    %add.i = add i16 %call.i.i, %call.i
    %add = add i16 %add.i, %call.i.6.i
    ret i16 %add
    }

    ; Function Attrs: nounwind readnone
    declare i16 @isnan(double) #2

    ; Function Attrs: nounwind readnone
    declare i16 @isinf(double) #2

    declare void @__cxa_pure_virtual()

    ; Function Attrs: nounwind readonly
    declare i16 @strlen(i8* nocapture) #3

    attributes #0 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #1 = { nounwind }
    attributes #2 = { nounwind readnone "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #3 = { nounwind readonly "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #4 = { nounwind readonly }
    attributes #5 = { nounwind readnone }

    !llvm.ident = !{!0}

    !0 = !{!"clang version 3.7.0 (https://github.com/llvm-mirror/clang.git 287e62c84a1ccd74fbca46bfc13e364e314d4b41) (https://github.com/llvm-mirror/llvm.git aaab572fc38b4438e769e2fd6b91963be11db7b2)"}
    !1 = !{!2, !2, i64 0}
    !2 = !{!"vtable pointer", !3, i64 0}
    !3 = !{!"Simple C/C++ TBAA"}
    !4 = !{!5, !5, i64 0}
    !5 = !{!"omnipotent char", !3, i64 0}
    !6 = !{i32 -2147062986, i32 -2147062977, i32 -2147062936}
    !7 = !{!8, !9, i64 0}
    !8 = !{!"_ZTS6String", !9, i64 0, !10, i64 2, !10, i64 4}
    !9 = !{!"any pointer", !5, i64 0}
    !10 = !{!"int", !5, i64 0}
    !11 = !{!8, !10, i64 4}
    1,012 changes: 1,012 additions & 0 deletions Stream.ll
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,1012 @@
    ; ModuleID = './Stream.cpp'
    target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-i64:8:8-f32:8:8-f64:8:8-n8"
    target triple = "avr"

    %class.Stream = type { %class.Print, i32, i32 }
    %class.Print = type { i32 (...)**, i16 }
    %class.String = type { i8*, i16, i16 }

    $__clang_call_terminate = comdat any

    @.str = private unnamed_addr constant [1 x i8] zeroinitializer, align 1

    define i16 @_ZN6Stream9timedReadEv(%class.Stream* %this) #0 align 2 {
    entry:
    %call = tail call i32 @millis()
    %_startMillis = getelementptr inbounds %class.Stream, %class.Stream* %this, i16 0, i32 2
    store i32 %call, i32* %_startMillis, align 2, !tbaa !1
    %0 = bitcast %class.Stream* %this to i16 (%class.Stream*)***
    %_timeout = getelementptr inbounds %class.Stream, %class.Stream* %this, i16 0, i32 1
    br label %do.body

    do.body: ; preds = %do.cond, %entry
    %vtable = load i16 (%class.Stream*)**, i16 (%class.Stream*)*** %0, align 1, !tbaa !6
    %vfn = getelementptr inbounds i16 (%class.Stream*)*, i16 (%class.Stream*)** %vtable, i16 3
    %1 = load i16 (%class.Stream*)*, i16 (%class.Stream*)** %vfn, align 1
    %call2 = tail call i16 %1(%class.Stream* %this)
    %cmp = icmp sgt i16 %call2, -1
    br i1 %cmp, label %cleanup, label %do.cond

    do.cond: ; preds = %do.body
    %call3 = tail call i32 @millis()
    %2 = load i32, i32* %_startMillis, align 2, !tbaa !1
    %sub = sub i32 %call3, %2
    %3 = load i32, i32* %_timeout, align 2, !tbaa !8
    %cmp5 = icmp ult i32 %sub, %3
    br i1 %cmp5, label %do.body, label %cleanup

    cleanup: ; preds = %do.cond, %do.body
    %retval.0 = phi i16 [ %call2, %do.body ], [ -1, %do.cond ]
    ret i16 %retval.0
    }

    declare i32 @millis() #0

    define i16 @_ZN6Stream9timedPeekEv(%class.Stream* %this) #0 align 2 {
    entry:
    %call = tail call i32 @millis()
    %_startMillis = getelementptr inbounds %class.Stream, %class.Stream* %this, i16 0, i32 2
    store i32 %call, i32* %_startMillis, align 2, !tbaa !1
    %0 = bitcast %class.Stream* %this to i16 (%class.Stream*)***
    %_timeout = getelementptr inbounds %class.Stream, %class.Stream* %this, i16 0, i32 1
    br label %do.body

    do.body: ; preds = %do.cond, %entry
    %vtable = load i16 (%class.Stream*)**, i16 (%class.Stream*)*** %0, align 1, !tbaa !6
    %vfn = getelementptr inbounds i16 (%class.Stream*)*, i16 (%class.Stream*)** %vtable, i16 4
    %1 = load i16 (%class.Stream*)*, i16 (%class.Stream*)** %vfn, align 1
    %call2 = tail call i16 %1(%class.Stream* %this)
    %cmp = icmp sgt i16 %call2, -1
    br i1 %cmp, label %cleanup, label %do.cond

    do.cond: ; preds = %do.body
    %call3 = tail call i32 @millis()
    %2 = load i32, i32* %_startMillis, align 2, !tbaa !1
    %sub = sub i32 %call3, %2
    %3 = load i32, i32* %_timeout, align 2, !tbaa !8
    %cmp5 = icmp ult i32 %sub, %3
    br i1 %cmp5, label %do.body, label %cleanup

    cleanup: ; preds = %do.cond, %do.body
    %retval.0 = phi i16 [ %call2, %do.body ], [ -1, %do.cond ]
    ret i16 %retval.0
    }

    define i16 @_ZN6Stream13peekNextDigitEv(%class.Stream* %this) #0 align 2 {
    entry:
    %_startMillis.i = getelementptr inbounds %class.Stream, %class.Stream* %this, i16 0, i32 2
    %0 = bitcast %class.Stream* %this to i16 (%class.Stream*)***
    %_timeout.i = getelementptr inbounds %class.Stream, %class.Stream* %this, i16 0, i32 1
    br label %while.body

    while.body: ; preds = %entry, %if.end.8
    %call.i = tail call i32 @millis()
    store i32 %call.i, i32* %_startMillis.i, align 2, !tbaa !1
    br label %do.body.i

    do.body.i: ; preds = %do.cond.i, %while.body
    %vtable.i = load i16 (%class.Stream*)**, i16 (%class.Stream*)*** %0, align 1, !tbaa !6
    %vfn.i = getelementptr inbounds i16 (%class.Stream*)*, i16 (%class.Stream*)** %vtable.i, i16 4
    %1 = load i16 (%class.Stream*)*, i16 (%class.Stream*)** %vfn.i, align 1
    %call2.i = tail call i16 %1(%class.Stream* %this)
    %cmp.i = icmp sgt i16 %call2.i, -1
    br i1 %cmp.i, label %_ZN6Stream9timedPeekEv.exit, label %do.cond.i

    do.cond.i: ; preds = %do.body.i
    %call3.i = tail call i32 @millis()
    %2 = load i32, i32* %_startMillis.i, align 2, !tbaa !1
    %sub.i = sub i32 %call3.i, %2
    %3 = load i32, i32* %_timeout.i, align 2, !tbaa !8
    %cmp5.i = icmp ult i32 %sub.i, %3
    br i1 %cmp5.i, label %do.body.i, label %cleanup.loopexit

    _ZN6Stream9timedPeekEv.exit: ; preds = %do.body.i
    %call2.i.lcssa = phi i16 [ %call2.i, %do.body.i ]
    %cmp2 = icmp eq i16 %call2.i.lcssa, 45
    %call.off = add i16 %call2.i.lcssa, -48
    %4 = icmp ult i16 %call.off, 10
    %or.cond16 = or i1 %cmp2, %4
    br i1 %or.cond16, label %cleanup.loopexit30, label %if.end.8

    if.end.8: ; preds = %_ZN6Stream9timedPeekEv.exit
    %vtable = load i16 (%class.Stream*)**, i16 (%class.Stream*)*** %0, align 1, !tbaa !6
    %vfn = getelementptr inbounds i16 (%class.Stream*)*, i16 (%class.Stream*)** %vtable, i16 3
    %5 = load i16 (%class.Stream*)*, i16 (%class.Stream*)** %vfn, align 1
    %call9 = tail call i16 %5(%class.Stream* %this)
    br label %while.body

    cleanup.loopexit: ; preds = %do.cond.i
    br label %cleanup

    cleanup.loopexit30: ; preds = %_ZN6Stream9timedPeekEv.exit
    %call2.i.lcssa.lcssa = phi i16 [ %call2.i.lcssa, %_ZN6Stream9timedPeekEv.exit ]
    br label %cleanup

    cleanup: ; preds = %cleanup.loopexit30, %cleanup.loopexit
    %retval.0.i22 = phi i16 [ -1, %cleanup.loopexit ], [ %call2.i.lcssa.lcssa, %cleanup.loopexit30 ]
    ret i16 %retval.0.i22
    }

    ; Function Attrs: nounwind
    define void @_ZN6Stream10setTimeoutEm(%class.Stream* nocapture %this, i32 %timeout) #1 align 2 {
    entry:
    %_timeout = getelementptr inbounds %class.Stream, %class.Stream* %this, i16 0, i32 1
    store i32 %timeout, i32* %_timeout, align 2, !tbaa !8
    ret void
    }

    define zeroext i1 @_ZN6Stream4findEPc(%class.Stream* %this, i8* nocapture readonly %target) #0 align 2 {
    entry:
    %call.i = tail call i16 @strlen(i8* %target) #4
    %call3.i = tail call zeroext i1 @_ZN6Stream9findUntilEPcjS0_j(%class.Stream* %this, i8* %target, i16 %call.i, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i16 0, i16 0), i16 0)
    ret i1 %call3.i
    }

    define zeroext i1 @_ZN6Stream9findUntilEPcS0_(%class.Stream* %this, i8* nocapture readonly %target, i8* nocapture readonly %terminator) #0 align 2 {
    entry:
    %call = tail call i16 @strlen(i8* %target) #4
    %call2 = tail call i16 @strlen(i8* %terminator) #4
    %call3 = tail call zeroext i1 @_ZN6Stream9findUntilEPcjS0_j(%class.Stream* %this, i8* %target, i16 %call, i8* %terminator, i16 %call2)
    ret i1 %call3
    }

    define zeroext i1 @_ZN6Stream4findEPcj(%class.Stream* %this, i8* nocapture readonly %target, i16 %length) #0 align 2 {
    entry:
    %0 = load i8, i8* %target, align 1, !tbaa !9
    %cmp.i = icmp eq i8 %0, 0
    br i1 %cmp.i, label %_ZN6Stream9findUntilEPcjS0_j.exit, label %while.cond.preheader.i

    while.cond.preheader.i: ; preds = %entry
    %_startMillis.i.i = getelementptr inbounds %class.Stream, %class.Stream* %this, i16 0, i32 2
    %1 = bitcast %class.Stream* %this to i16 (%class.Stream*)***
    %_timeout.i.i = getelementptr inbounds %class.Stream, %class.Stream* %this, i16 0, i32 1
    br label %while.cond.i

    while.cond.i: ; preds = %while.cond.i.backedge, %while.cond.preheader.i
    %index.0.i = phi i16 [ 0, %while.cond.preheader.i ], [ %index.0.i.be, %while.cond.i.backedge ]
    %call.i.i = tail call i32 @millis()
    store i32 %call.i.i, i32* %_startMillis.i.i, align 2, !tbaa !1
    br label %do.body.i.i

    do.body.i.i: ; preds = %do.cond.i.i, %while.cond.i
    %vtable.i.i = load i16 (%class.Stream*)**, i16 (%class.Stream*)*** %1, align 1, !tbaa !6
    %vfn.i.i = getelementptr inbounds i16 (%class.Stream*)*, i16 (%class.Stream*)** %vtable.i.i, i16 3
    %2 = load i16 (%class.Stream*)*, i16 (%class.Stream*)** %vfn.i.i, align 1
    %call2.i.i = tail call i16 %2(%class.Stream* %this)
    %cmp.i.i = icmp sgt i16 %call2.i.i, -1
    br i1 %cmp.i.i, label %_ZN6Stream9timedReadEv.exit.i, label %do.cond.i.i

    do.cond.i.i: ; preds = %do.body.i.i
    %call3.i.i = tail call i32 @millis()
    %3 = load i32, i32* %_startMillis.i.i, align 2, !tbaa !1
    %sub.i.i = sub i32 %call3.i.i, %3
    %4 = load i32, i32* %_timeout.i.i, align 2, !tbaa !8
    %cmp5.i.i = icmp ult i32 %sub.i.i, %4
    br i1 %cmp5.i.i, label %do.body.i.i, label %_ZN6Stream9findUntilEPcjS0_j.exit.loopexit

    _ZN6Stream9timedReadEv.exit.i: ; preds = %do.body.i.i
    %call2.i.i.lcssa = phi i16 [ %call2.i.i, %do.body.i.i ]
    %cmp2.i = icmp sgt i16 %call2.i.i.lcssa, 0
    br i1 %cmp2.i, label %while.body.i, label %_ZN6Stream9findUntilEPcjS0_j.exit.loopexit9

    while.body.i: ; preds = %_ZN6Stream9timedReadEv.exit.i
    %arrayidx.i = getelementptr inbounds i8, i8* %target, i16 %index.0.i
    %5 = load i8, i8* %arrayidx.i, align 1, !tbaa !9
    %conv3.i = sext i8 %5 to i16
    %cmp4.i = icmp eq i16 %call2.i.i.lcssa, %conv3.i
    %index.0..i = select i1 %cmp4.i, i16 %index.0.i, i16 0
    %arrayidx7.i = getelementptr inbounds i8, i8* %target, i16 %index.0..i
    %6 = load i8, i8* %arrayidx7.i, align 1, !tbaa !9
    %conv8.i = sext i8 %6 to i16
    %cmp9.i = icmp eq i16 %call2.i.i.lcssa, %conv8.i
    br i1 %cmp9.i, label %if.then.10.i, label %while.cond.i.backedge

    if.then.10.i: ; preds = %while.body.i
    %inc.i = add i16 %index.0..i, 1
    %cmp11.i = icmp ult i16 %inc.i, %length
    br i1 %cmp11.i, label %while.cond.i.backedge, label %_ZN6Stream9findUntilEPcjS0_j.exit.loopexit9

    while.cond.i.backedge: ; preds = %if.then.10.i, %while.body.i
    %index.0.i.be = phi i16 [ %inc.i, %if.then.10.i ], [ %index.0..i, %while.body.i ]
    br label %while.cond.i

    _ZN6Stream9findUntilEPcjS0_j.exit.loopexit: ; preds = %do.cond.i.i
    br label %_ZN6Stream9findUntilEPcjS0_j.exit

    _ZN6Stream9findUntilEPcjS0_j.exit.loopexit9: ; preds = %if.then.10.i, %_ZN6Stream9timedReadEv.exit.i
    %retval.0.i.ph = phi i1 [ true, %if.then.10.i ], [ false, %_ZN6Stream9timedReadEv.exit.i ]
    br label %_ZN6Stream9findUntilEPcjS0_j.exit

    _ZN6Stream9findUntilEPcjS0_j.exit: ; preds = %_ZN6Stream9findUntilEPcjS0_j.exit.loopexit9, %_ZN6Stream9findUntilEPcjS0_j.exit.loopexit, %entry
    %retval.0.i = phi i1 [ true, %entry ], [ false, %_ZN6Stream9findUntilEPcjS0_j.exit.loopexit ], [ %retval.0.i.ph, %_ZN6Stream9findUntilEPcjS0_j.exit.loopexit9 ]
    ret i1 %retval.0.i
    }

    define zeroext i1 @_ZN6Stream9findUntilEPcjS0_j(%class.Stream* %this, i8* nocapture readonly %target, i16 %targetLen, i8* nocapture readonly %terminator, i16 %termLen) #0 align 2 {
    entry:
    %0 = load i8, i8* %target, align 1, !tbaa !9
    %cmp = icmp eq i8 %0, 0
    br i1 %cmp, label %cleanup, label %while.cond.preheader

    while.cond.preheader: ; preds = %entry
    %_startMillis.i = getelementptr inbounds %class.Stream, %class.Stream* %this, i16 0, i32 2
    %1 = bitcast %class.Stream* %this to i16 (%class.Stream*)***
    %_timeout.i = getelementptr inbounds %class.Stream, %class.Stream* %this, i16 0, i32 1
    %cmp15 = icmp eq i16 %termLen, 0
    br label %while.cond

    while.cond: ; preds = %while.cond.backedge, %while.cond.preheader
    %index.0 = phi i16 [ 0, %while.cond.preheader ], [ %index.2, %while.cond.backedge ]
    %termIndex.0 = phi i16 [ 0, %while.cond.preheader ], [ %termIndex.0.be, %while.cond.backedge ]
    %call.i = tail call i32 @millis()
    store i32 %call.i, i32* %_startMillis.i, align 2, !tbaa !1
    br label %do.body.i

    do.body.i: ; preds = %do.cond.i, %while.cond
    %vtable.i = load i16 (%class.Stream*)**, i16 (%class.Stream*)*** %1, align 1, !tbaa !6
    %vfn.i = getelementptr inbounds i16 (%class.Stream*)*, i16 (%class.Stream*)** %vtable.i, i16 3
    %2 = load i16 (%class.Stream*)*, i16 (%class.Stream*)** %vfn.i, align 1
    %call2.i = tail call i16 %2(%class.Stream* %this)
    %cmp.i = icmp sgt i16 %call2.i, -1
    br i1 %cmp.i, label %_ZN6Stream9timedReadEv.exit, label %do.cond.i

    do.cond.i: ; preds = %do.body.i
    %call3.i = tail call i32 @millis()
    %3 = load i32, i32* %_startMillis.i, align 2, !tbaa !1
    %sub.i = sub i32 %call3.i, %3
    %4 = load i32, i32* %_timeout.i, align 2, !tbaa !8
    %cmp5.i = icmp ult i32 %sub.i, %4
    br i1 %cmp5.i, label %do.body.i, label %cleanup.loopexit

    _ZN6Stream9timedReadEv.exit: ; preds = %do.body.i
    %call2.i.lcssa = phi i16 [ %call2.i, %do.body.i ]
    %cmp2 = icmp sgt i16 %call2.i.lcssa, 0
    br i1 %cmp2, label %while.body, label %cleanup.loopexit46

    while.body: ; preds = %_ZN6Stream9timedReadEv.exit
    %arrayidx = getelementptr inbounds i8, i8* %target, i16 %index.0
    %5 = load i8, i8* %arrayidx, align 1, !tbaa !9
    %conv3 = sext i8 %5 to i16
    %cmp4 = icmp eq i16 %call2.i.lcssa, %conv3
    %index.0. = select i1 %cmp4, i16 %index.0, i16 0
    %arrayidx7 = getelementptr inbounds i8, i8* %target, i16 %index.0.
    %6 = load i8, i8* %arrayidx7, align 1, !tbaa !9
    %conv8 = sext i8 %6 to i16
    %cmp9 = icmp eq i16 %call2.i.lcssa, %conv8
    br i1 %cmp9, label %if.then.10, label %if.end.14

    if.then.10: ; preds = %while.body
    %inc = add i16 %index.0., 1
    %cmp11 = icmp ult i16 %inc, %targetLen
    br i1 %cmp11, label %if.end.14, label %cleanup.loopexit46

    if.end.14: ; preds = %if.then.10, %while.body
    %index.2 = phi i16 [ %inc, %if.then.10 ], [ %index.0., %while.body ]
    br i1 %cmp15, label %while.cond.backedge, label %land.lhs.true

    land.lhs.true: ; preds = %if.end.14
    %arrayidx16 = getelementptr inbounds i8, i8* %terminator, i16 %termIndex.0
    %7 = load i8, i8* %arrayidx16, align 1, !tbaa !9
    %conv17 = sext i8 %7 to i16
    %cmp18 = icmp eq i16 %call2.i.lcssa, %conv17
    br i1 %cmp18, label %if.then.19, label %while.cond.backedge

    if.then.19: ; preds = %land.lhs.true
    %inc20 = add i16 %termIndex.0, 1
    %cmp21 = icmp ult i16 %inc20, %termLen
    br i1 %cmp21, label %while.cond.backedge, label %cleanup.loopexit46

    while.cond.backedge: ; preds = %if.then.19, %if.end.14, %land.lhs.true
    %termIndex.0.be = phi i16 [ %inc20, %if.then.19 ], [ 0, %if.end.14 ], [ 0, %land.lhs.true ]
    br label %while.cond

    cleanup.loopexit: ; preds = %do.cond.i
    br label %cleanup

    cleanup.loopexit46: ; preds = %if.then.10, %if.then.19, %_ZN6Stream9timedReadEv.exit
    %retval.0.ph = phi i1 [ true, %if.then.10 ], [ false, %if.then.19 ], [ false, %_ZN6Stream9timedReadEv.exit ]
    br label %cleanup

    cleanup: ; preds = %cleanup.loopexit46, %cleanup.loopexit, %entry
    %retval.0 = phi i1 [ true, %entry ], [ false, %cleanup.loopexit ], [ %retval.0.ph, %cleanup.loopexit46 ]
    ret i1 %retval.0
    }

    ; Function Attrs: nounwind readonly
    declare i16 @strlen(i8* nocapture) #2

    define i32 @_ZN6Stream8parseIntEv(%class.Stream* %this) #0 align 2 {
    entry:
    %call = tail call i32 @_ZN6Stream8parseIntEc(%class.Stream* %this, i8 signext 1)
    ret i32 %call
    }

    define i32 @_ZN6Stream8parseIntEc(%class.Stream* %this, i8 signext %skipChar) #0 align 2 {
    entry:
    %_startMillis.i.i = getelementptr inbounds %class.Stream, %class.Stream* %this, i16 0, i32 2
    %0 = bitcast %class.Stream* %this to i16 (%class.Stream*)***
    %_timeout.i.i = getelementptr inbounds %class.Stream, %class.Stream* %this, i16 0, i32 1
    br label %while.body.i

    while.body.i: ; preds = %if.end.8.i, %entry
    %call.i.i = tail call i32 @millis()
    store i32 %call.i.i, i32* %_startMillis.i.i, align 2, !tbaa !1
    br label %do.body.i.i

    do.body.i.i: ; preds = %do.cond.i.i, %while.body.i
    %vtable.i.i = load i16 (%class.Stream*)**, i16 (%class.Stream*)*** %0, align 1, !tbaa !6
    %vfn.i.i = getelementptr inbounds i16 (%class.Stream*)*, i16 (%class.Stream*)** %vtable.i.i, i16 4
    %1 = load i16 (%class.Stream*)*, i16 (%class.Stream*)** %vfn.i.i, align 1
    %call2.i.i = tail call i16 %1(%class.Stream* %this)
    %cmp.i.i = icmp sgt i16 %call2.i.i, -1
    br i1 %cmp.i.i, label %_ZN6Stream9timedPeekEv.exit.i, label %do.cond.i.i

    do.cond.i.i: ; preds = %do.body.i.i
    %call3.i.i = tail call i32 @millis()
    %2 = load i32, i32* %_startMillis.i.i, align 2, !tbaa !1
    %sub.i.i = sub i32 %call3.i.i, %2
    %3 = load i32, i32* %_timeout.i.i, align 2, !tbaa !8
    %cmp5.i.i = icmp ult i32 %sub.i.i, %3
    br i1 %cmp5.i.i, label %do.body.i.i, label %cleanup.loopexit

    _ZN6Stream9timedPeekEv.exit.i: ; preds = %do.body.i.i
    %call2.i.i.lcssa = phi i16 [ %call2.i.i, %do.body.i.i ]
    %cmp2.i = icmp eq i16 %call2.i.i.lcssa, 45
    %call.off.i = add i16 %call2.i.i.lcssa, -48
    %4 = icmp ult i16 %call.off.i, 10
    %or.cond16.i = or i1 %cmp2.i, %4
    br i1 %or.cond16.i, label %do.body.preheader, label %if.end.8.i

    do.body.preheader: ; preds = %_ZN6Stream9timedPeekEv.exit.i
    %call2.i.i.lcssa.lcssa = phi i16 [ %call2.i.i.lcssa, %_ZN6Stream9timedPeekEv.exit.i ]
    %conv = sext i8 %skipChar to i16
    br label %do.body

    if.end.8.i: ; preds = %_ZN6Stream9timedPeekEv.exit.i
    %vtable.i = load i16 (%class.Stream*)**, i16 (%class.Stream*)*** %0, align 1, !tbaa !6
    %vfn.i = getelementptr inbounds i16 (%class.Stream*)*, i16 (%class.Stream*)** %vtable.i, i16 3
    %5 = load i16 (%class.Stream*)*, i16 (%class.Stream*)** %vfn.i, align 1
    %call9.i = tail call i16 %5(%class.Stream* %this)
    br label %while.body.i

    do.body: ; preds = %do.body.preheader, %_ZN6Stream9timedPeekEv.exit
    %isNegative.0 = phi i8 [ %isNegative.1, %_ZN6Stream9timedPeekEv.exit ], [ 0, %do.body.preheader ]
    %value.0 = phi i32 [ %value.1, %_ZN6Stream9timedPeekEv.exit ], [ 0, %do.body.preheader ]
    %c.0 = phi i16 [ %retval.0.i, %_ZN6Stream9timedPeekEv.exit ], [ %call2.i.i.lcssa.lcssa, %do.body.preheader ]
    %cmp2 = icmp eq i16 %c.0, %conv
    br i1 %cmp2, label %if.end.13, label %if.else

    if.else: ; preds = %do.body
    %cmp4 = icmp eq i16 %c.0, 45
    br i1 %cmp4, label %if.end.13, label %if.else.6

    if.else.6: ; preds = %if.else
    %c.0.off = add i16 %c.0, -48
    %6 = icmp ult i16 %c.0.off, 10
    br i1 %6, label %if.then.9, label %if.end.13

    if.then.9: ; preds = %if.else.6
    %mul = mul nsw i32 %value.0, 10
    %conv10 = sext i16 %c.0 to i32
    %add = add i32 %mul, -48
    %sub = add i32 %add, %conv10
    br label %if.end.13

    if.end.13: ; preds = %if.else, %if.then.9, %if.else.6, %do.body
    %isNegative.1 = phi i8 [ %isNegative.0, %do.body ], [ %isNegative.0, %if.then.9 ], [ %isNegative.0, %if.else.6 ], [ 1, %if.else ]
    %value.1 = phi i32 [ %value.0, %do.body ], [ %sub, %if.then.9 ], [ %value.0, %if.else.6 ], [ %value.0, %if.else ]
    %vtable = load i16 (%class.Stream*)**, i16 (%class.Stream*)*** %0, align 1, !tbaa !6
    %vfn = getelementptr inbounds i16 (%class.Stream*)*, i16 (%class.Stream*)** %vtable, i16 3
    %7 = load i16 (%class.Stream*)*, i16 (%class.Stream*)** %vfn, align 1
    %call14 = tail call i16 %7(%class.Stream* %this)
    %call.i = tail call i32 @millis()
    store i32 %call.i, i32* %_startMillis.i.i, align 2, !tbaa !1
    br label %do.body.i

    do.body.i: ; preds = %do.cond.i, %if.end.13
    %vtable.i.40 = load i16 (%class.Stream*)**, i16 (%class.Stream*)*** %0, align 1, !tbaa !6
    %vfn.i.41 = getelementptr inbounds i16 (%class.Stream*)*, i16 (%class.Stream*)** %vtable.i.40, i16 4
    %8 = load i16 (%class.Stream*)*, i16 (%class.Stream*)** %vfn.i.41, align 1
    %call2.i = tail call i16 %8(%class.Stream* %this)
    %cmp.i = icmp sgt i16 %call2.i, -1
    br i1 %cmp.i, label %_ZN6Stream9timedPeekEv.exit, label %do.cond.i

    do.cond.i: ; preds = %do.body.i
    %call3.i = tail call i32 @millis()
    %9 = load i32, i32* %_startMillis.i.i, align 2, !tbaa !1
    %sub.i = sub i32 %call3.i, %9
    %10 = load i32, i32* %_timeout.i.i, align 2, !tbaa !8
    %cmp5.i = icmp ult i32 %sub.i, %10
    br i1 %cmp5.i, label %do.body.i, label %_ZN6Stream9timedPeekEv.exit

    _ZN6Stream9timedPeekEv.exit: ; preds = %do.body.i, %do.cond.i
    %retval.0.i = phi i16 [ %call2.i, %do.body.i ], [ -1, %do.cond.i ]
    %call15.off = add i16 %retval.0.i, -48
    %11 = icmp ult i16 %call15.off, 10
    %cmp20 = icmp eq i16 %retval.0.i, %conv
    %or.cond = or i1 %cmp20, %11
    br i1 %or.cond, label %do.body, label %do.end

    do.end: ; preds = %_ZN6Stream9timedPeekEv.exit
    %value.1.lcssa = phi i32 [ %value.1, %_ZN6Stream9timedPeekEv.exit ]
    %isNegative.1.lcssa = phi i8 [ %isNegative.1, %_ZN6Stream9timedPeekEv.exit ]
    %12 = and i8 %isNegative.1.lcssa, 1
    %tobool = icmp eq i8 %12, 0
    %sub22 = sub nsw i32 0, %value.1.lcssa
    %value.1.sub22 = select i1 %tobool, i32 %value.1.lcssa, i32 %sub22
    br label %cleanup

    cleanup.loopexit: ; preds = %do.cond.i.i
    br label %cleanup

    cleanup: ; preds = %cleanup.loopexit, %do.end
    %retval.0 = phi i32 [ %value.1.sub22, %do.end ], [ 0, %cleanup.loopexit ]
    ret i32 %retval.0
    }

    define float @_ZN6Stream10parseFloatEv(%class.Stream* %this) #0 align 2 {
    entry:
    %call = tail call float @_ZN6Stream10parseFloatEc(%class.Stream* %this, i8 signext 1)
    ret float %call
    }

    define float @_ZN6Stream10parseFloatEc(%class.Stream* %this, i8 signext %skipChar) #0 align 2 {
    entry:
    %_startMillis.i.i = getelementptr inbounds %class.Stream, %class.Stream* %this, i16 0, i32 2
    %0 = bitcast %class.Stream* %this to i16 (%class.Stream*)***
    %_timeout.i.i = getelementptr inbounds %class.Stream, %class.Stream* %this, i16 0, i32 1
    br label %while.body.i

    while.body.i: ; preds = %if.end.8.i, %entry
    %call.i.i = tail call i32 @millis()
    store i32 %call.i.i, i32* %_startMillis.i.i, align 2, !tbaa !1
    br label %do.body.i.i

    do.body.i.i: ; preds = %do.cond.i.i, %while.body.i
    %vtable.i.i = load i16 (%class.Stream*)**, i16 (%class.Stream*)*** %0, align 1, !tbaa !6
    %vfn.i.i = getelementptr inbounds i16 (%class.Stream*)*, i16 (%class.Stream*)** %vtable.i.i, i16 4
    %1 = load i16 (%class.Stream*)*, i16 (%class.Stream*)** %vfn.i.i, align 1
    %call2.i.i = tail call i16 %1(%class.Stream* %this)
    %cmp.i.i = icmp sgt i16 %call2.i.i, -1
    br i1 %cmp.i.i, label %_ZN6Stream9timedPeekEv.exit.i, label %do.cond.i.i

    do.cond.i.i: ; preds = %do.body.i.i
    %call3.i.i = tail call i32 @millis()
    %2 = load i32, i32* %_startMillis.i.i, align 2, !tbaa !1
    %sub.i.i = sub i32 %call3.i.i, %2
    %3 = load i32, i32* %_timeout.i.i, align 2, !tbaa !8
    %cmp5.i.i = icmp ult i32 %sub.i.i, %3
    br i1 %cmp5.i.i, label %do.body.i.i, label %cleanup

    _ZN6Stream9timedPeekEv.exit.i: ; preds = %do.body.i.i
    %call2.i.i.lcssa = phi i16 [ %call2.i.i, %do.body.i.i ]
    %cmp2.i = icmp eq i16 %call2.i.i.lcssa, 45
    %call.off.i = add i16 %call2.i.i.lcssa, -48
    %4 = icmp ult i16 %call.off.i, 10
    %or.cond16.i = or i1 %cmp2.i, %4
    br i1 %or.cond16.i, label %do.body.preheader, label %if.end.8.i

    do.body.preheader: ; preds = %_ZN6Stream9timedPeekEv.exit.i
    %call2.i.i.lcssa.lcssa = phi i16 [ %call2.i.i.lcssa, %_ZN6Stream9timedPeekEv.exit.i ]
    %conv = sext i8 %skipChar to i16
    br label %do.body

    if.end.8.i: ; preds = %_ZN6Stream9timedPeekEv.exit.i
    %vtable.i = load i16 (%class.Stream*)**, i16 (%class.Stream*)*** %0, align 1, !tbaa !6
    %vfn.i = getelementptr inbounds i16 (%class.Stream*)*, i16 (%class.Stream*)** %vtable.i, i16 3
    %5 = load i16 (%class.Stream*)*, i16 (%class.Stream*)** %vfn.i, align 1
    %call9.i = tail call i16 %5(%class.Stream* %this)
    br label %while.body.i

    do.body: ; preds = %do.body.preheader, %_ZN6Stream9timedPeekEv.exit
    %isNegative.0 = phi i8 [ %isNegative.1, %_ZN6Stream9timedPeekEv.exit ], [ 0, %do.body.preheader ]
    %isFraction.0 = phi i8 [ %isFraction.1, %_ZN6Stream9timedPeekEv.exit ], [ 0, %do.body.preheader ]
    %value.0 = phi i32 [ %value.1, %_ZN6Stream9timedPeekEv.exit ], [ 0, %do.body.preheader ]
    %c.0 = phi i16 [ %retval.0.i, %_ZN6Stream9timedPeekEv.exit ], [ %call2.i.i.lcssa.lcssa, %do.body.preheader ]
    %fraction.0 = phi float [ %fraction.1, %_ZN6Stream9timedPeekEv.exit ], [ 1.000000e+00, %do.body.preheader ]
    %cmp2 = icmp eq i16 %c.0, %conv
    br i1 %cmp2, label %if.end.22, label %if.else

    if.else: ; preds = %do.body
    switch i16 %c.0, label %if.else.9 [
    i16 45, label %if.end.22
    i16 46, label %if.then.8
    ]

    if.then.8: ; preds = %if.else
    br label %if.end.22

    if.else.9: ; preds = %if.else
    %c.0.off = add i16 %c.0, -48
    %6 = icmp ult i16 %c.0.off, 10
    br i1 %6, label %if.then.12, label %if.end.22

    if.then.12: ; preds = %if.else.9
    %mul = mul nsw i32 %value.0, 10
    %conv13 = sext i16 %c.0 to i32
    %add = add i32 %mul, -48
    %sub = add i32 %add, %conv13
    %7 = and i8 %isFraction.0, 1
    %tobool = icmp eq i8 %7, 0
    br i1 %tobool, label %if.end.22, label %if.then.14

    if.then.14: ; preds = %if.then.12
    %conv15 = fpext float %fraction.0 to double
    %mul16 = fmul double %conv15, 1.000000e-01
    %conv17 = fptrunc double %mul16 to float
    br label %if.end.22

    if.end.22: ; preds = %if.else, %if.then.12, %if.else.9, %if.then.14, %if.then.8, %do.body
    %isNegative.1 = phi i8 [ %isNegative.0, %do.body ], [ %isNegative.0, %if.then.8 ], [ %isNegative.0, %if.then.14 ], [ %isNegative.0, %if.then.12 ], [ %isNegative.0, %if.else.9 ], [ 1, %if.else ]
    %isFraction.1 = phi i8 [ %isFraction.0, %do.body ], [ 1, %if.then.8 ], [ %isFraction.0, %if.then.14 ], [ %isFraction.0, %if.then.12 ], [ %isFraction.0, %if.else.9 ], [ %isFraction.0, %if.else ]
    %value.1 = phi i32 [ %value.0, %do.body ], [ %value.0, %if.then.8 ], [ %sub, %if.then.14 ], [ %sub, %if.then.12 ], [ %value.0, %if.else.9 ], [ %value.0, %if.else ]
    %fraction.1 = phi float [ %fraction.0, %do.body ], [ %fraction.0, %if.then.8 ], [ %conv17, %if.then.14 ], [ %fraction.0, %if.then.12 ], [ %fraction.0, %if.else.9 ], [ %fraction.0, %if.else ]
    %vtable = load i16 (%class.Stream*)**, i16 (%class.Stream*)*** %0, align 1, !tbaa !6
    %vfn = getelementptr inbounds i16 (%class.Stream*)*, i16 (%class.Stream*)** %vtable, i16 3
    %8 = load i16 (%class.Stream*)*, i16 (%class.Stream*)** %vfn, align 1
    %call23 = tail call i16 %8(%class.Stream* %this)
    %call.i = tail call i32 @millis()
    store i32 %call.i, i32* %_startMillis.i.i, align 2, !tbaa !1
    br label %do.body.i

    do.body.i: ; preds = %do.cond.i, %if.end.22
    %vtable.i.65 = load i16 (%class.Stream*)**, i16 (%class.Stream*)*** %0, align 1, !tbaa !6
    %vfn.i.66 = getelementptr inbounds i16 (%class.Stream*)*, i16 (%class.Stream*)** %vtable.i.65, i16 4
    %9 = load i16 (%class.Stream*)*, i16 (%class.Stream*)** %vfn.i.66, align 1
    %call2.i = tail call i16 %9(%class.Stream* %this)
    %cmp.i = icmp sgt i16 %call2.i, -1
    br i1 %cmp.i, label %_ZN6Stream9timedPeekEv.exit, label %do.cond.i

    do.cond.i: ; preds = %do.body.i
    %call3.i = tail call i32 @millis()
    %10 = load i32, i32* %_startMillis.i.i, align 2, !tbaa !1
    %sub.i = sub i32 %call3.i, %10
    %11 = load i32, i32* %_timeout.i.i, align 2, !tbaa !8
    %cmp5.i = icmp ult i32 %sub.i, %11
    br i1 %cmp5.i, label %do.body.i, label %_ZN6Stream9timedPeekEv.exit

    _ZN6Stream9timedPeekEv.exit: ; preds = %do.body.i, %do.cond.i
    %retval.0.i = phi i16 [ %call2.i, %do.body.i ], [ -1, %do.cond.i ]
    %call24.off = add i16 %retval.0.i, -48
    %12 = icmp ult i16 %call24.off, 10
    %cmp28 = icmp eq i16 %retval.0.i, 46
    %or.cond46 = or i1 %cmp28, %12
    %cmp30 = icmp eq i16 %retval.0.i, %conv
    %or.cond = or i1 %cmp30, %or.cond46
    br i1 %or.cond, label %do.body, label %do.end

    do.end: ; preds = %_ZN6Stream9timedPeekEv.exit
    %fraction.1.lcssa = phi float [ %fraction.1, %_ZN6Stream9timedPeekEv.exit ]
    %value.1.lcssa = phi i32 [ %value.1, %_ZN6Stream9timedPeekEv.exit ]
    %isFraction.1.lcssa = phi i8 [ %isFraction.1, %_ZN6Stream9timedPeekEv.exit ]
    %isNegative.1.lcssa = phi i8 [ %isNegative.1, %_ZN6Stream9timedPeekEv.exit ]
    %13 = and i8 %isNegative.1.lcssa, 1
    %tobool31 = icmp eq i8 %13, 0
    %sub33 = sub nsw i32 0, %value.1.lcssa
    %value.1.sub33 = select i1 %tobool31, i32 %value.1.lcssa, i32 %sub33
    %14 = and i8 %isFraction.1.lcssa, 1
    %tobool35 = icmp eq i8 %14, 0
    %conv37 = sitofp i32 %value.1.sub33 to float
    %mul38 = fmul float %fraction.1.lcssa, %conv37
    %conv37.mul38 = select i1 %tobool35, float %conv37, float %mul38
    ret float %conv37.mul38

    cleanup: ; preds = %do.cond.i.i
    ret float 0.000000e+00
    }

    define i16 @_ZN6Stream9readBytesEPcj(%class.Stream* %this, i8* nocapture %buffer, i16 %length) #0 align 2 {
    entry:
    %cmp.17 = icmp eq i16 %length, 0
    br i1 %cmp.17, label %while.end, label %while.body.lr.ph

    while.body.lr.ph: ; preds = %entry
    %_startMillis.i = getelementptr inbounds %class.Stream, %class.Stream* %this, i16 0, i32 2
    %0 = bitcast %class.Stream* %this to i16 (%class.Stream*)***
    %_timeout.i = getelementptr inbounds %class.Stream, %class.Stream* %this, i16 0, i32 1
    br label %while.body

    while.body: ; preds = %while.body.lr.ph, %cleanup.thread
    %buffer.addr.019 = phi i8* [ %buffer, %while.body.lr.ph ], [ %incdec.ptr, %cleanup.thread ]
    %count.018 = phi i16 [ 0, %while.body.lr.ph ], [ %inc, %cleanup.thread ]
    %call.i = tail call i32 @millis()
    store i32 %call.i, i32* %_startMillis.i, align 2, !tbaa !1
    br label %do.body.i

    do.body.i: ; preds = %do.cond.i, %while.body
    %vtable.i = load i16 (%class.Stream*)**, i16 (%class.Stream*)*** %0, align 1, !tbaa !6
    %vfn.i = getelementptr inbounds i16 (%class.Stream*)*, i16 (%class.Stream*)** %vtable.i, i16 3
    %1 = load i16 (%class.Stream*)*, i16 (%class.Stream*)** %vfn.i, align 1
    %call2.i = tail call i16 %1(%class.Stream* %this)
    %cmp.i = icmp sgt i16 %call2.i, -1
    br i1 %cmp.i, label %cleanup.thread, label %do.cond.i

    do.cond.i: ; preds = %do.body.i
    %call3.i = tail call i32 @millis()
    %2 = load i32, i32* %_startMillis.i, align 2, !tbaa !1
    %sub.i = sub i32 %call3.i, %2
    %3 = load i32, i32* %_timeout.i, align 2, !tbaa !8
    %cmp5.i = icmp ult i32 %sub.i, %3
    br i1 %cmp5.i, label %do.body.i, label %while.end.loopexit

    cleanup.thread: ; preds = %do.body.i
    %call2.i.lcssa = phi i16 [ %call2.i, %do.body.i ]
    %conv = trunc i16 %call2.i.lcssa to i8
    %incdec.ptr = getelementptr inbounds i8, i8* %buffer.addr.019, i16 1
    store i8 %conv, i8* %buffer.addr.019, align 1, !tbaa !9
    %inc = add nuw i16 %count.018, 1
    %cmp = icmp ult i16 %inc, %length
    br i1 %cmp, label %while.body, label %while.end.loopexit28

    while.end.loopexit: ; preds = %do.cond.i
    %count.018.lcssa = phi i16 [ %count.018, %do.cond.i ]
    br label %while.end

    while.end.loopexit28: ; preds = %cleanup.thread
    %inc.lcssa = phi i16 [ %inc, %cleanup.thread ]
    br label %while.end

    while.end: ; preds = %while.end.loopexit28, %while.end.loopexit, %entry
    %count.016 = phi i16 [ 0, %entry ], [ %count.018.lcssa, %while.end.loopexit ], [ %inc.lcssa, %while.end.loopexit28 ]
    ret i16 %count.016
    }

    define i16 @_ZN6Stream14readBytesUntilEcPcj(%class.Stream* %this, i8 signext %terminator, i8* nocapture %buffer, i16 %length) #0 align 2 {
    entry:
    %cmp = icmp eq i16 %length, 0
    br i1 %cmp, label %return, label %while.body.lr.ph

    while.body.lr.ph: ; preds = %entry
    %_startMillis.i = getelementptr inbounds %class.Stream, %class.Stream* %this, i16 0, i32 2
    %0 = bitcast %class.Stream* %this to i16 (%class.Stream*)***
    %_timeout.i = getelementptr inbounds %class.Stream, %class.Stream* %this, i16 0, i32 1
    %conv = sext i8 %terminator to i16
    br label %while.body

    while.body: ; preds = %while.body.lr.ph, %cleanup
    %index.025 = phi i16 [ 0, %while.body.lr.ph ], [ %inc, %cleanup ]
    %buffer.addr.024 = phi i8* [ %buffer, %while.body.lr.ph ], [ %incdec.ptr, %cleanup ]
    %call.i = tail call i32 @millis()
    store i32 %call.i, i32* %_startMillis.i, align 2, !tbaa !1
    br label %do.body.i

    do.body.i: ; preds = %do.cond.i, %while.body
    %vtable.i = load i16 (%class.Stream*)**, i16 (%class.Stream*)*** %0, align 1, !tbaa !6
    %vfn.i = getelementptr inbounds i16 (%class.Stream*)*, i16 (%class.Stream*)** %vtable.i, i16 3
    %1 = load i16 (%class.Stream*)*, i16 (%class.Stream*)** %vfn.i, align 1
    %call2.i = tail call i16 %1(%class.Stream* %this)
    %cmp.i = icmp sgt i16 %call2.i, -1
    br i1 %cmp.i, label %_ZN6Stream9timedReadEv.exit, label %do.cond.i

    do.cond.i: ; preds = %do.body.i
    %call3.i = tail call i32 @millis()
    %2 = load i32, i32* %_startMillis.i, align 2, !tbaa !1
    %sub.i = sub i32 %call3.i, %2
    %3 = load i32, i32* %_timeout.i, align 2, !tbaa !8
    %cmp5.i = icmp ult i32 %sub.i, %3
    br i1 %cmp5.i, label %do.body.i, label %return.loopexit

    _ZN6Stream9timedReadEv.exit: ; preds = %do.body.i
    %call2.i.lcssa = phi i16 [ %call2.i, %do.body.i ]
    %cmp4 = icmp eq i16 %call2.i.lcssa, %conv
    br i1 %cmp4, label %return.loopexit36, label %cleanup

    cleanup: ; preds = %_ZN6Stream9timedReadEv.exit
    %conv7 = trunc i16 %call2.i.lcssa to i8
    %incdec.ptr = getelementptr inbounds i8, i8* %buffer.addr.024, i16 1
    store i8 %conv7, i8* %buffer.addr.024, align 1, !tbaa !9
    %inc = add nuw i16 %index.025, 1
    %cmp2 = icmp ult i16 %inc, %length
    br i1 %cmp2, label %while.body, label %return.loopexit36

    return.loopexit: ; preds = %do.cond.i
    %index.025.lcssa = phi i16 [ %index.025, %do.cond.i ]
    br label %return

    return.loopexit36: ; preds = %_ZN6Stream9timedReadEv.exit, %cleanup
    %retval.0.ph = phi i16 [ %index.025, %_ZN6Stream9timedReadEv.exit ], [ %inc, %cleanup ]
    br label %return

    return: ; preds = %return.loopexit36, %return.loopexit, %entry
    %retval.0 = phi i16 [ 0, %entry ], [ %index.025.lcssa, %return.loopexit ], [ %retval.0.ph, %return.loopexit36 ]
    ret i16 %retval.0
    }

    define void @_ZN6Stream10readStringEv(%class.String* noalias sret %agg.result, %class.Stream* %this) #0 align 2 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
    entry:
    tail call void @_ZN6StringC1EPKc(%class.String* %agg.result, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i16 0, i16 0))
    %call.i10 = invoke i32 @millis()
    to label %call.i.noexc unwind label %lpad.loopexit.split-lp.loopexit.split-lp.loopexit.split-lp

    call.i.noexc: ; preds = %entry
    %_startMillis.i = getelementptr inbounds %class.Stream, %class.Stream* %this, i16 0, i32 2
    store i32 %call.i10, i32* %_startMillis.i, align 2, !tbaa !1
    %0 = bitcast %class.Stream* %this to i16 (%class.Stream*)***
    %_timeout.i = getelementptr inbounds %class.Stream, %class.Stream* %this, i16 0, i32 1
    br label %do.body.i

    do.body.i: ; preds = %call3.i.noexc, %call.i.noexc
    %vtable.i = load i16 (%class.Stream*)**, i16 (%class.Stream*)*** %0, align 1, !tbaa !6
    %vfn.i = getelementptr inbounds i16 (%class.Stream*)*, i16 (%class.Stream*)** %vtable.i, i16 3
    %1 = load i16 (%class.Stream*)*, i16 (%class.Stream*)** %vfn.i, align 1
    %call2.i11 = invoke i16 %1(%class.Stream* %this)
    to label %call2.i.noexc unwind label %lpad.loopexit.split-lp.loopexit.split-lp.loopexit

    call2.i.noexc: ; preds = %do.body.i
    %cmp.i = icmp sgt i16 %call2.i11, -1
    br i1 %cmp.i, label %while.body.preheader, label %do.cond.i

    while.body.preheader: ; preds = %call2.i.noexc
    %call2.i11.lcssa = phi i16 [ %call2.i11, %call2.i.noexc ]
    %extract.t61 = trunc i16 %call2.i11.lcssa to i8
    br label %while.body

    do.cond.i: ; preds = %call2.i.noexc
    %call3.i12 = invoke i32 @millis()
    to label %call3.i.noexc unwind label %lpad.loopexit.split-lp.loopexit.split-lp.loopexit

    call3.i.noexc: ; preds = %do.cond.i
    %2 = load i32, i32* %_startMillis.i, align 2, !tbaa !1
    %sub.i = sub i32 %call3.i12, %2
    %3 = load i32, i32* %_timeout.i, align 2, !tbaa !8
    %cmp5.i = icmp ult i32 %sub.i, %3
    br i1 %cmp5.i, label %do.body.i, label %nrvo.skipdtor.loopexit62

    while.body.loopexit: ; preds = %call2.i.noexc27
    %call2.i28.lcssa = phi i16 [ %call2.i28, %call2.i.noexc27 ]
    %extract.t = trunc i16 %call2.i28.lcssa to i8
    br label %while.body

    while.body: ; preds = %while.body.preheader, %while.body.loopexit
    %call2.i11.sink.off0 = phi i8 [ %extract.t, %while.body.loopexit ], [ %extract.t61, %while.body.preheader ]
    %call.i14 = invoke zeroext i8 @_ZN6String6concatEc(%class.String* %agg.result, i8 signext %call2.i11.sink.off0)
    to label %invoke.cont.2 unwind label %lpad.loopexit.split-lp.loopexit

    invoke.cont.2: ; preds = %while.body
    %call.i26 = invoke i32 @millis()
    to label %call.i.noexc25 unwind label %lpad.loopexit.split-lp.loopexit

    call.i.noexc25: ; preds = %invoke.cont.2
    store i32 %call.i26, i32* %_startMillis.i, align 2, !tbaa !1
    br label %do.body.i.20

    do.body.i.20: ; preds = %call3.i.noexc29, %call.i.noexc25
    %vtable.i.17 = load i16 (%class.Stream*)**, i16 (%class.Stream*)*** %0, align 1, !tbaa !6
    %vfn.i.18 = getelementptr inbounds i16 (%class.Stream*)*, i16 (%class.Stream*)** %vtable.i.17, i16 3
    %4 = load i16 (%class.Stream*)*, i16 (%class.Stream*)** %vfn.i.18, align 1
    %call2.i28 = invoke i16 %4(%class.Stream* %this)
    to label %call2.i.noexc27 unwind label %lpad.loopexit

    call2.i.noexc27: ; preds = %do.body.i.20
    %cmp.i.19 = icmp sgt i16 %call2.i28, -1
    br i1 %cmp.i.19, label %while.body.loopexit, label %do.cond.i.23

    do.cond.i.23: ; preds = %call2.i.noexc27
    %call3.i30 = invoke i32 @millis()
    to label %call3.i.noexc29 unwind label %lpad.loopexit

    call3.i.noexc29: ; preds = %do.cond.i.23
    %5 = load i32, i32* %_startMillis.i, align 2, !tbaa !1
    %sub.i.21 = sub i32 %call3.i30, %5
    %6 = load i32, i32* %_timeout.i, align 2, !tbaa !8
    %cmp5.i.22 = icmp ult i32 %sub.i.21, %6
    br i1 %cmp5.i.22, label %do.body.i.20, label %nrvo.skipdtor.loopexit

    lpad.loopexit: ; preds = %do.body.i.20, %do.cond.i.23
    %lpad.loopexit.32 = landingpad { i8*, i32 }
    cleanup
    br label %lpad

    lpad.loopexit.split-lp.loopexit: ; preds = %invoke.cont.2, %while.body
    %lpad.loopexit.35 = landingpad { i8*, i32 }
    cleanup
    br label %lpad

    lpad.loopexit.split-lp.loopexit.split-lp.loopexit: ; preds = %do.body.i, %do.cond.i
    %lpad.loopexit.38 = landingpad { i8*, i32 }
    cleanup
    br label %lpad

    lpad.loopexit.split-lp.loopexit.split-lp.loopexit.split-lp: ; preds = %entry
    %lpad.loopexit.split-lp.39 = landingpad { i8*, i32 }
    cleanup
    br label %lpad

    lpad: ; preds = %lpad.loopexit.split-lp.loopexit, %lpad.loopexit.split-lp.loopexit.split-lp.loopexit.split-lp, %lpad.loopexit.split-lp.loopexit.split-lp.loopexit, %lpad.loopexit
    %lpad.phi = phi { i8*, i32 } [ %lpad.loopexit.32, %lpad.loopexit ], [ %lpad.loopexit.35, %lpad.loopexit.split-lp.loopexit ], [ %lpad.loopexit.38, %lpad.loopexit.split-lp.loopexit.split-lp.loopexit ], [ %lpad.loopexit.split-lp.39, %lpad.loopexit.split-lp.loopexit.split-lp.loopexit.split-lp ]
    invoke void @_ZN6StringD1Ev(%class.String* %agg.result)
    to label %eh.resume unwind label %terminate.lpad

    nrvo.skipdtor.loopexit: ; preds = %call3.i.noexc29
    br label %nrvo.skipdtor

    nrvo.skipdtor.loopexit62: ; preds = %call3.i.noexc
    br label %nrvo.skipdtor

    nrvo.skipdtor: ; preds = %nrvo.skipdtor.loopexit62, %nrvo.skipdtor.loopexit
    ret void

    eh.resume: ; preds = %lpad
    resume { i8*, i32 } %lpad.phi

    terminate.lpad: ; preds = %lpad
    %7 = landingpad { i8*, i32 }
    catch i8* null
    %8 = extractvalue { i8*, i32 } %7, 0
    tail call void @__clang_call_terminate(i8* %8) #5
    unreachable
    }

    declare void @_ZN6StringC1EPKc(%class.String*, i8*) #0

    declare i32 @__gxx_personality_v0(...)

    declare void @_ZN6StringD1Ev(%class.String*) #0

    ; Function Attrs: noinline noreturn nounwind
    define linkonce_odr hidden void @__clang_call_terminate(i8*) #3 comdat {
    %2 = tail call i8* @__cxa_begin_catch(i8* %0) #6
    tail call void @_ZSt9terminatev() #5
    unreachable
    }

    declare i8* @__cxa_begin_catch(i8*)

    declare void @_ZSt9terminatev()

    define void @_ZN6Stream15readStringUntilEc(%class.String* noalias sret %agg.result, %class.Stream* %this, i8 signext %terminator) #0 align 2 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
    entry:
    tail call void @_ZN6StringC1EPKc(%class.String* %agg.result, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i16 0, i16 0))
    %call.i13 = invoke i32 @millis()
    to label %call.i.noexc unwind label %lpad.loopexit.split-lp.loopexit.split-lp.loopexit.split-lp

    call.i.noexc: ; preds = %entry
    %_startMillis.i = getelementptr inbounds %class.Stream, %class.Stream* %this, i16 0, i32 2
    store i32 %call.i13, i32* %_startMillis.i, align 2, !tbaa !1
    %0 = bitcast %class.Stream* %this to i16 (%class.Stream*)***
    %_timeout.i = getelementptr inbounds %class.Stream, %class.Stream* %this, i16 0, i32 1
    br label %do.body.i

    do.body.i: ; preds = %call3.i.noexc, %call.i.noexc
    %vtable.i = load i16 (%class.Stream*)**, i16 (%class.Stream*)*** %0, align 1, !tbaa !6
    %vfn.i = getelementptr inbounds i16 (%class.Stream*)*, i16 (%class.Stream*)** %vtable.i, i16 3
    %1 = load i16 (%class.Stream*)*, i16 (%class.Stream*)** %vfn.i, align 1
    %call2.i14 = invoke i16 %1(%class.Stream* %this)
    to label %call2.i.noexc unwind label %lpad.loopexit.split-lp.loopexit.split-lp.loopexit

    call2.i.noexc: ; preds = %do.body.i
    %cmp.i = icmp sgt i16 %call2.i14, -1
    br i1 %cmp.i, label %while.cond.preheader, label %do.cond.i

    do.cond.i: ; preds = %call2.i.noexc
    %call3.i15 = invoke i32 @millis()
    to label %call3.i.noexc unwind label %lpad.loopexit.split-lp.loopexit.split-lp.loopexit

    call3.i.noexc: ; preds = %do.cond.i
    %2 = load i32, i32* %_startMillis.i, align 2, !tbaa !1
    %sub.i = sub i32 %call3.i15, %2
    %3 = load i32, i32* %_timeout.i, align 2, !tbaa !8
    %cmp5.i = icmp ult i32 %sub.i, %3
    br i1 %cmp5.i, label %do.body.i, label %nrvo.skipdtor.loopexit66

    while.cond.preheader: ; preds = %call2.i.noexc
    %call2.i14.lcssa = phi i16 [ %call2.i14, %call2.i.noexc ]
    %conv = sext i8 %terminator to i16
    %cmp2.45 = icmp eq i16 %call2.i14.lcssa, %conv
    br i1 %cmp2.45, label %nrvo.skipdtor, label %while.body.lr.ph

    while.body.lr.ph: ; preds = %while.cond.preheader
    %extract.t = trunc i16 %call2.i14.lcssa to i8
    br label %while.body

    while.cond.loopexit: ; preds = %call2.i.noexc30
    %call2.i31.lcssa = phi i16 [ %call2.i31, %call2.i.noexc30 ]
    %cmp2 = icmp eq i16 %call2.i31.lcssa, %conv
    %extract.t48 = trunc i16 %call2.i31.lcssa to i8
    br i1 %cmp2, label %nrvo.skipdtor.loopexit65, label %while.body

    while.body: ; preds = %while.body.lr.ph, %while.cond.loopexit
    %c.047.off0 = phi i8 [ %extract.t, %while.body.lr.ph ], [ %extract.t48, %while.cond.loopexit ]
    %call.i17 = invoke zeroext i8 @_ZN6String6concatEc(%class.String* %agg.result, i8 signext %c.047.off0)
    to label %invoke.cont.4 unwind label %lpad.loopexit.split-lp.loopexit

    invoke.cont.4: ; preds = %while.body
    %call.i29 = invoke i32 @millis()
    to label %call.i.noexc28 unwind label %lpad.loopexit.split-lp.loopexit

    call.i.noexc28: ; preds = %invoke.cont.4
    store i32 %call.i29, i32* %_startMillis.i, align 2, !tbaa !1
    br label %do.body.i.23

    do.body.i.23: ; preds = %call3.i.noexc32, %call.i.noexc28
    %vtable.i.20 = load i16 (%class.Stream*)**, i16 (%class.Stream*)*** %0, align 1, !tbaa !6
    %vfn.i.21 = getelementptr inbounds i16 (%class.Stream*)*, i16 (%class.Stream*)** %vtable.i.20, i16 3
    %4 = load i16 (%class.Stream*)*, i16 (%class.Stream*)** %vfn.i.21, align 1
    %call2.i31 = invoke i16 %4(%class.Stream* %this)
    to label %call2.i.noexc30 unwind label %lpad.loopexit

    call2.i.noexc30: ; preds = %do.body.i.23
    %cmp.i.22 = icmp sgt i16 %call2.i31, -1
    br i1 %cmp.i.22, label %while.cond.loopexit, label %do.cond.i.26

    do.cond.i.26: ; preds = %call2.i.noexc30
    %call3.i33 = invoke i32 @millis()
    to label %call3.i.noexc32 unwind label %lpad.loopexit

    call3.i.noexc32: ; preds = %do.cond.i.26
    %5 = load i32, i32* %_startMillis.i, align 2, !tbaa !1
    %sub.i.24 = sub i32 %call3.i33, %5
    %6 = load i32, i32* %_timeout.i, align 2, !tbaa !8
    %cmp5.i.25 = icmp ult i32 %sub.i.24, %6
    br i1 %cmp5.i.25, label %do.body.i.23, label %nrvo.skipdtor.loopexit

    lpad.loopexit: ; preds = %do.body.i.23, %do.cond.i.26
    %lpad.loopexit.35 = landingpad { i8*, i32 }
    cleanup
    br label %lpad

    lpad.loopexit.split-lp.loopexit: ; preds = %invoke.cont.4, %while.body
    %lpad.loopexit.38 = landingpad { i8*, i32 }
    cleanup
    br label %lpad

    lpad.loopexit.split-lp.loopexit.split-lp.loopexit: ; preds = %do.body.i, %do.cond.i
    %lpad.loopexit.41 = landingpad { i8*, i32 }
    cleanup
    br label %lpad

    lpad.loopexit.split-lp.loopexit.split-lp.loopexit.split-lp: ; preds = %entry
    %lpad.loopexit.split-lp.42 = landingpad { i8*, i32 }
    cleanup
    br label %lpad

    lpad: ; preds = %lpad.loopexit.split-lp.loopexit, %lpad.loopexit.split-lp.loopexit.split-lp.loopexit.split-lp, %lpad.loopexit.split-lp.loopexit.split-lp.loopexit, %lpad.loopexit
    %lpad.phi = phi { i8*, i32 } [ %lpad.loopexit.35, %lpad.loopexit ], [ %lpad.loopexit.38, %lpad.loopexit.split-lp.loopexit ], [ %lpad.loopexit.41, %lpad.loopexit.split-lp.loopexit.split-lp.loopexit ], [ %lpad.loopexit.split-lp.42, %lpad.loopexit.split-lp.loopexit.split-lp.loopexit.split-lp ]
    invoke void @_ZN6StringD1Ev(%class.String* %agg.result)
    to label %eh.resume unwind label %terminate.lpad

    nrvo.skipdtor.loopexit: ; preds = %call3.i.noexc32
    br label %nrvo.skipdtor

    nrvo.skipdtor.loopexit65: ; preds = %while.cond.loopexit
    br label %nrvo.skipdtor

    nrvo.skipdtor.loopexit66: ; preds = %call3.i.noexc
    br label %nrvo.skipdtor

    nrvo.skipdtor: ; preds = %nrvo.skipdtor.loopexit66, %nrvo.skipdtor.loopexit65, %nrvo.skipdtor.loopexit, %while.cond.preheader
    ret void

    eh.resume: ; preds = %lpad
    resume { i8*, i32 } %lpad.phi

    terminate.lpad: ; preds = %lpad
    %7 = landingpad { i8*, i32 }
    catch i8* null
    %8 = extractvalue { i8*, i32 } %7, 0
    tail call void @__clang_call_terminate(i8* %8) #5
    unreachable
    }

    declare zeroext i8 @_ZN6String6concatEc(%class.String*, i8 signext) #0

    attributes #0 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #1 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #2 = { nounwind readonly "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #3 = { noinline noreturn nounwind }
    attributes #4 = { nounwind readonly }
    attributes #5 = { noreturn nounwind }
    attributes #6 = { nounwind }

    !llvm.ident = !{!0}

    !0 = !{!"clang version 3.7.0 (https://github.com/llvm-mirror/clang.git 287e62c84a1ccd74fbca46bfc13e364e314d4b41) (https://github.com/llvm-mirror/llvm.git aaab572fc38b4438e769e2fd6b91963be11db7b2)"}
    !1 = !{!2, !3, i64 8}
    !2 = !{!"_ZTS6Stream", !3, i64 4, !3, i64 8}
    !3 = !{!"long", !4, i64 0}
    !4 = !{!"omnipotent char", !5, i64 0}
    !5 = !{!"Simple C/C++ TBAA"}
    !6 = !{!7, !7, i64 0}
    !7 = !{!"vtable pointer", !5, i64 0}
    !8 = !{!2, !3, i64 4}
    !9 = !{!4, !4, i64 0}
    7 changes: 7 additions & 0 deletions USBCore.ll
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,7 @@
    ; ModuleID = './USBCore.cpp'
    target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-i64:8:8-f32:8:8-f64:8:8-n8"
    target triple = "avr"

    !llvm.ident = !{!0}

    !0 = !{!"clang version 3.7.0 (https://github.com/llvm-mirror/clang.git 287e62c84a1ccd74fbca46bfc13e364e314d4b41) (https://github.com/llvm-mirror/llvm.git aaab572fc38b4438e769e2fd6b91963be11db7b2)"}
    96 changes: 96 additions & 0 deletions WMath.ll
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,96 @@
    ; ModuleID = './WMath.cpp'
    target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-i64:8:8-f32:8:8-f64:8:8-n8"
    target triple = "avr"

    define void @_Z10randomSeedj(i16 %seed) #0 {
    entry:
    %cmp = icmp eq i16 %seed, 0
    br i1 %cmp, label %if.end, label %if.then

    if.then: ; preds = %entry
    %conv = zext i16 %seed to i32
    tail call void @srandom(i32 %conv)
    br label %if.end

    if.end: ; preds = %entry, %if.then
    ret void
    }

    declare void @srandom(i32) #0

    define i32 @_Z6randoml(i32 %howbig) #0 {
    entry:
    %cmp = icmp eq i32 %howbig, 0
    br i1 %cmp, label %return, label %if.end

    if.end: ; preds = %entry
    %call = tail call i32 @random()
    %rem = srem i32 %call, %howbig
    br label %return

    return: ; preds = %entry, %if.end
    %retval.0 = phi i32 [ %rem, %if.end ], [ 0, %entry ]
    ret i32 %retval.0
    }

    declare i32 @random() #0

    define i32 @_Z6randomll(i32 %howsmall, i32 %howbig) #0 {
    entry:
    %cmp = icmp sgt i32 %howbig, %howsmall
    br i1 %cmp, label %if.end, label %return

    if.end: ; preds = %entry
    %cmp.i = icmp eq i32 %howbig, %howsmall
    br i1 %cmp.i, label %_Z6randoml.exit, label %if.end.i

    if.end.i: ; preds = %if.end
    %sub = sub nsw i32 %howbig, %howsmall
    %call.i = tail call i32 @random()
    %rem.i = srem i32 %call.i, %sub
    br label %_Z6randoml.exit

    _Z6randoml.exit: ; preds = %if.end, %if.end.i
    %retval.0.i = phi i32 [ %rem.i, %if.end.i ], [ 0, %if.end ]
    %add = add nsw i32 %retval.0.i, %howsmall
    br label %return

    return: ; preds = %entry, %_Z6randoml.exit
    %retval.0 = phi i32 [ %add, %_Z6randoml.exit ], [ %howsmall, %entry ]
    ret i32 %retval.0
    }

    ; Function Attrs: nounwind readnone
    define i32 @_Z3maplllll(i32 %x, i32 %in_min, i32 %in_max, i32 %out_min, i32 %out_max) #1 {
    entry:
    %sub = sub nsw i32 %x, %in_min
    %sub1 = sub nsw i32 %out_max, %out_min
    %mul = mul nsw i32 %sub1, %sub
    %sub2 = sub nsw i32 %in_max, %in_min
    %div = sdiv i32 %mul, %sub2
    %add = add nsw i32 %div, %out_min
    ret i32 %add
    }

    ; Function Attrs: nounwind readnone
    define i16 @_Z8makeWordj(i16 %w) #1 {
    entry:
    ret i16 %w
    }

    ; Function Attrs: nounwind readnone
    define i16 @_Z8makeWordhh(i8 zeroext %h, i8 zeroext %l) #1 {
    entry:
    %conv = zext i8 %h to i16
    %shl = shl nuw i16 %conv, 8
    %conv1 = zext i8 %l to i16
    %or = or i16 %shl, %conv1
    ret i16 %or
    }

    attributes #0 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #1 = { nounwind readnone "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }

    !llvm.ident = !{!0}

    !0 = !{!"clang version 3.7.0 (https://github.com/llvm-mirror/clang.git 287e62c84a1ccd74fbca46bfc13e364e314d4b41) (https://github.com/llvm-mirror/llvm.git aaab572fc38b4438e769e2fd6b91963be11db7b2)"}
    3,482 changes: 3,482 additions & 0 deletions WString.ll
    3,482 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
    27 changes: 27 additions & 0 deletions abi.ll
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,27 @@
    ; ModuleID = './abi.cpp'
    target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-i64:8:8-f32:8:8-f64:8:8-n8"
    target triple = "avr"

    ; Function Attrs: noreturn
    define void @__cxa_pure_virtual() #0 {
    entry:
    tail call void @abort() #1
    unreachable
    }

    ; Function Attrs: noreturn
    declare void @abort() #0

    ; Function Attrs: noreturn
    define void @__cxa_deleted_virtual() #0 {
    entry:
    tail call void @abort() #1
    unreachable
    }

    attributes #0 = { noreturn "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #1 = { noreturn }

    !llvm.ident = !{!0}

    !0 = !{!"clang version 3.7.0 (https://github.com/llvm-mirror/clang.git 287e62c84a1ccd74fbca46bfc13e364e314d4b41) (https://github.com/llvm-mirror/llvm.git aaab572fc38b4438e769e2fd6b91963be11db7b2)"}
    17 changes: 17 additions & 0 deletions hooks.ll
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,17 @@
    ; ModuleID = './hooks.c'
    target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-i64:8:8-f32:8:8-f64:8:8-n8"
    target triple = "avr"

    @yield = weak alias void ()* @__empty

    ; Function Attrs: nounwind readnone
    define internal void @__empty() #0 {
    entry:
    ret void
    }

    attributes #0 = { nounwind readnone "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }

    !llvm.ident = !{!0}

    !0 = !{!"clang version 3.7.0 (https://github.com/llvm-mirror/clang.git 287e62c84a1ccd74fbca46bfc13e364e314d4b41) (https://github.com/llvm-mirror/llvm.git aaab572fc38b4438e769e2fd6b91963be11db7b2)"}
    48 changes: 48 additions & 0 deletions main.ll
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,48 @@
    ; ModuleID = './main.cpp'
    target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-i64:8:8-f32:8:8-f64:8:8-n8"
    target triple = "avr"

    define weak i16 @atexit(void ()* %func) #0 {
    entry:
    ret i16 0
    }

    define weak void @initVariant() #0 {
    entry:
    ret void
    }

    ; Function Attrs: noreturn
    define i16 @main() #1 {
    entry:
    tail call void @init()
    tail call void @initVariant()
    tail call void @setup()
    br label %for.cond

    for.cond: ; preds = %for.cond.backedge, %entry
    tail call void @loop()
    br i1 icmp ne (void ()* @_Z14serialEventRunv, void ()* null), label %if.then, label %for.cond.backedge

    if.then: ; preds = %for.cond
    tail call void @_Z14serialEventRunv()
    br label %for.cond.backedge

    for.cond.backedge: ; preds = %if.then, %for.cond
    br label %for.cond
    }

    declare void @init() #0

    declare void @setup() #0

    declare void @loop() #0

    declare extern_weak void @_Z14serialEventRunv() #0

    attributes #0 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #1 = { noreturn "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }

    !llvm.ident = !{!0}

    !0 = !{!"clang version 3.7.0 (https://github.com/llvm-mirror/clang.git 287e62c84a1ccd74fbca46bfc13e364e314d4b41) (https://github.com/llvm-mirror/llvm.git aaab572fc38b4438e769e2fd6b91963be11db7b2)"}
    47 changes: 47 additions & 0 deletions new.ll
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,47 @@
    ; ModuleID = './new.cpp'
    target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-i64:8:8-f32:8:8-f64:8:8-n8"
    target triple = "avr"

    ; Function Attrs: nobuiltin
    define noalias i8* @_Znwj(i16 %size) #0 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
    invoke.cont:
    %call = tail call noalias i8* @malloc(i16 %size)
    ret i8* %call
    }

    ; Function Attrs: nounwind
    declare noalias i8* @malloc(i16) #1

    declare i32 @__gxx_personality_v0(...)

    ; Function Attrs: nobuiltin
    define noalias i8* @_Znaj(i16 %size) #0 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
    invoke.cont:
    %call = tail call noalias i8* @malloc(i16 %size)
    ret i8* %call
    }

    ; Function Attrs: nobuiltin nounwind
    define void @_ZdlPv(i8* nocapture %ptr) #2 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
    invoke.cont:
    tail call void @free(i8* %ptr)
    ret void
    }

    ; Function Attrs: nounwind
    declare void @free(i8* nocapture) #1

    ; Function Attrs: nobuiltin nounwind
    define void @_ZdaPv(i8* nocapture %ptr) #2 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
    invoke.cont:
    tail call void @free(i8* %ptr)
    ret void
    }

    attributes #0 = { nobuiltin "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #1 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #2 = { nobuiltin nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }

    !llvm.ident = !{!0}

    !0 = !{!"clang version 3.7.0 (https://github.com/llvm-mirror/clang.git 287e62c84a1ccd74fbca46bfc13e364e314d4b41) (https://github.com/llvm-mirror/llvm.git aaab572fc38b4438e769e2fd6b91963be11db7b2)"}
    156 changes: 156 additions & 0 deletions wiring_analog.ll
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,156 @@
    ; ModuleID = './wiring_analog.c'
    target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-i64:8:8-f32:8:8-f64:8:8-n8"
    target triple = "avr"

    @analog_reference = global i8 1, align 1
    @digital_pin_to_timer_PGM = external constant [0 x i8], align 1

    ; Function Attrs: nounwind
    define void @analogReference(i8 zeroext %mode) #0 {
    entry:
    store i8 %mode, i8* @analog_reference, align 1, !tbaa !1
    ret void
    }

    ; Function Attrs: nounwind
    define i16 @analogRead(i8 zeroext %pin) #0 {
    entry:
    %cmp = icmp ugt i8 %pin, 13
    %sub = add i8 %pin, 2
    %sub.pin = select i1 %cmp, i8 %sub, i8 %pin
    %0 = load i8, i8* @analog_reference, align 1, !tbaa !1
    %shl = shl i8 %0, 6
    %and = and i8 %sub.pin, 7
    %or = or i8 %shl, %and
    store volatile i8 %or, i8* inttoptr (i16 124 to i8*), align 4, !tbaa !1
    %1 = load volatile i8, i8* inttoptr (i16 122 to i8*), align 2, !tbaa !1
    %or8 = or i8 %1, 64
    store volatile i8 %or8, i8* inttoptr (i16 122 to i8*), align 2, !tbaa !1
    br label %while.cond

    while.cond: ; preds = %while.cond, %entry
    %2 = load volatile i8, i8* inttoptr (i16 122 to i8*), align 2, !tbaa !1
    %and11 = and i8 %2, 64
    %tobool = icmp eq i8 %and11, 0
    br i1 %tobool, label %while.end, label %while.cond

    while.end: ; preds = %while.cond
    %3 = load volatile i8, i8* inttoptr (i16 120 to i8*), align 8, !tbaa !1
    %4 = load volatile i8, i8* inttoptr (i16 121 to i8*), align 1, !tbaa !1
    %conv12 = zext i8 %4 to i16
    %shl13 = shl nuw i16 %conv12, 8
    %conv14 = zext i8 %3 to i16
    %or15 = or i16 %shl13, %conv14
    ret i16 %or15
    }

    ; Function Attrs: nounwind
    define void @analogWrite(i8 zeroext %pin, i16 %val) #0 {
    entry:
    tail call void @pinMode(i8 zeroext %pin, i8 zeroext 1) #2
    switch i16 %val, label %if.else.3 [
    i16 0, label %if.then
    i16 255, label %if.then.2
    ]

    if.then: ; preds = %entry
    tail call void @digitalWrite(i8 zeroext %pin, i8 zeroext 0) #2
    br label %if.end.37

    if.then.2: ; preds = %entry
    tail call void @digitalWrite(i8 zeroext %pin, i8 zeroext 1) #2
    br label %if.end.37

    if.else.3: ; preds = %entry
    %conv = zext i8 %pin to i16
    %add.ptr = getelementptr inbounds [0 x i8], [0 x i8]* @digital_pin_to_timer_PGM, i16 0, i16 %conv
    %0 = ptrtoint i8* %add.ptr to i16
    %1 = tail call i8 asm sideeffect "lpm\0A\09mov $0, r0\0A\09", "=r,z,~{r0}"(i16 %0) #2, !srcloc !4
    switch i8 %1, label %sw.default [
    i8 1, label %sw.bb
    i8 2, label %sw.bb.8
    i8 3, label %sw.bb.13
    i8 4, label %sw.bb.17
    i8 7, label %sw.bb.21
    i8 8, label %sw.bb.26
    ]

    sw.bb: ; preds = %if.else.3
    %2 = load volatile i8, i8* inttoptr (i16 68 to i8*), align 4, !tbaa !1
    %or = or i8 %2, -128
    store volatile i8 %or, i8* inttoptr (i16 68 to i8*), align 4, !tbaa !1
    %conv7 = trunc i16 %val to i8
    store volatile i8 %conv7, i8* inttoptr (i16 71 to i8*), align 1, !tbaa !1
    br label %if.end.37

    sw.bb.8: ; preds = %if.else.3
    %3 = load volatile i8, i8* inttoptr (i16 68 to i8*), align 4, !tbaa !1
    %or10 = or i8 %3, 32
    store volatile i8 %or10, i8* inttoptr (i16 68 to i8*), align 4, !tbaa !1
    %conv12 = trunc i16 %val to i8
    store volatile i8 %conv12, i8* inttoptr (i16 72 to i8*), align 8, !tbaa !1
    br label %if.end.37

    sw.bb.13: ; preds = %if.else.3
    %4 = load volatile i8, i8* inttoptr (i16 128 to i8*), align 128, !tbaa !1
    %or15 = or i8 %4, -128
    store volatile i8 %or15, i8* inttoptr (i16 128 to i8*), align 128, !tbaa !1
    store volatile i16 %val, i16* inttoptr (i16 136 to i16*), align 8, !tbaa !5
    br label %if.end.37

    sw.bb.17: ; preds = %if.else.3
    %5 = load volatile i8, i8* inttoptr (i16 128 to i8*), align 128, !tbaa !1
    %or19 = or i8 %5, 32
    store volatile i8 %or19, i8* inttoptr (i16 128 to i8*), align 128, !tbaa !1
    store volatile i16 %val, i16* inttoptr (i16 138 to i16*), align 2, !tbaa !5
    br label %if.end.37

    sw.bb.21: ; preds = %if.else.3
    %6 = load volatile i8, i8* inttoptr (i16 176 to i8*), align 16, !tbaa !1
    %or23 = or i8 %6, -128
    store volatile i8 %or23, i8* inttoptr (i16 176 to i8*), align 16, !tbaa !1
    %conv25 = trunc i16 %val to i8
    store volatile i8 %conv25, i8* inttoptr (i16 179 to i8*), align 1, !tbaa !1
    br label %if.end.37

    sw.bb.26: ; preds = %if.else.3
    %7 = load volatile i8, i8* inttoptr (i16 176 to i8*), align 16, !tbaa !1
    %or28 = or i8 %7, 32
    store volatile i8 %or28, i8* inttoptr (i16 176 to i8*), align 16, !tbaa !1
    %conv30 = trunc i16 %val to i8
    store volatile i8 %conv30, i8* inttoptr (i16 180 to i8*), align 4, !tbaa !1
    br label %if.end.37

    sw.default: ; preds = %if.else.3
    %cmp32 = icmp slt i16 %val, 128
    br i1 %cmp32, label %if.then.34, label %if.else.35

    if.then.34: ; preds = %sw.default
    tail call void @digitalWrite(i8 zeroext %pin, i8 zeroext 0) #2
    br label %if.end.37

    if.else.35: ; preds = %sw.default
    tail call void @digitalWrite(i8 zeroext %pin, i8 zeroext 1) #2
    br label %if.end.37

    if.end.37: ; preds = %if.then.2, %if.then.34, %if.else.35, %sw.bb.26, %sw.bb.21, %sw.bb.17, %sw.bb.13, %sw.bb.8, %sw.bb, %if.then
    ret void
    }

    declare void @pinMode(i8 zeroext, i8 zeroext) #1

    declare void @digitalWrite(i8 zeroext, i8 zeroext) #1

    attributes #0 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #1 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #2 = { nounwind }

    !llvm.ident = !{!0}

    !0 = !{!"clang version 3.7.0 (https://github.com/llvm-mirror/clang.git 287e62c84a1ccd74fbca46bfc13e364e314d4b41) (https://github.com/llvm-mirror/llvm.git aaab572fc38b4438e769e2fd6b91963be11db7b2)"}
    !1 = !{!2, !2, i64 0}
    !2 = !{!"omnipotent char", !3, i64 0}
    !3 = !{!"Simple C/C++ TBAA"}
    !4 = !{i32 -2147149877, i32 -2147149868, i32 -2147149827}
    !5 = !{!6, !6, i64 0}
    !6 = !{!"short", !2, i64 0}
    285 changes: 285 additions & 0 deletions wiring_digital.ll
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,285 @@
    ; ModuleID = './wiring_digital.c'
    target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-i64:8:8-f32:8:8-f64:8:8-n8"
    target triple = "avr"

    @port_to_mode_PGM = constant [5 x i16] [i16 0, i16 0, i16 36, i16 39, i16 42], section ".progmem", align 2
    @port_to_output_PGM = constant [5 x i16] [i16 0, i16 0, i16 37, i16 40, i16 43], section ".progmem", align 2
    @port_to_input_PGM = constant [5 x i16] [i16 0, i16 0, i16 35, i16 38, i16 41], section ".progmem", align 2
    @digital_pin_to_port_PGM = constant [20 x i8] c"\04\04\04\04\04\04\04\04\02\02\02\02\02\02\03\03\03\03\03\03", section ".progmem", align 1
    @digital_pin_to_bit_mask_PGM = constant [20 x i8] c"\01\02\04\08\10 @\80\01\02\04\08\10 \01\02\04\08\10 ", section ".progmem", align 1
    @digital_pin_to_timer_PGM = constant [20 x i8] c"\00\00\00\08\00\02\01\00\00\03\04\07\00\00\00\00\00\00\00\00", section ".progmem", align 1

    ; Function Attrs: nounwind
    define void @pinMode(i8 zeroext %pin, i8 zeroext %mode) #0 {
    entry:
    %conv = zext i8 %pin to i16
    %add.ptr = getelementptr inbounds [20 x i8], [20 x i8]* @digital_pin_to_bit_mask_PGM, i16 0, i16 %conv
    %0 = ptrtoint i8* %add.ptr to i16
    %1 = tail call i8 asm sideeffect "lpm\0A\09mov $0, r0\0A\09", "=r,z,~{r0}"(i16 %0) #1, !srcloc !1
    %add.ptr5 = getelementptr inbounds [20 x i8], [20 x i8]* @digital_pin_to_port_PGM, i16 0, i16 %conv
    %2 = ptrtoint i8* %add.ptr5 to i16
    %3 = tail call i8 asm sideeffect "lpm\0A\09mov $0, r0\0A\09", "=r,z,~{r0}"(i16 %2) #1, !srcloc !2
    %conv11 = zext i8 %3 to i16
    %cmp = icmp eq i8 %3, 0
    br i1 %cmp, label %cleanup, label %if.end

    if.end: ; preds = %entry
    %add.ptr16 = getelementptr inbounds [5 x i16], [5 x i16]* @port_to_mode_PGM, i16 0, i16 %conv11
    %4 = ptrtoint i16* %add.ptr16 to i16
    %5 = tail call { i16, i16 } asm sideeffect "lpm\0A\09mov ${0:A}, r0\0A\09adiw r30, 1\0A\09lpm\0A\09mov ${0:B}, r0\0A\09", "=r,=z,1,~{r0}"(i16 %4) #1, !srcloc !3
    %asmresult = extractvalue { i16, i16 } %5, 0
    %6 = inttoptr i16 %asmresult to i8*
    %add.ptr24 = getelementptr inbounds [5 x i16], [5 x i16]* @port_to_output_PGM, i16 0, i16 %conv11
    %7 = ptrtoint i16* %add.ptr24 to i16
    %8 = tail call { i16, i16 } asm sideeffect "lpm\0A\09mov ${0:A}, r0\0A\09adiw r30, 1\0A\09lpm\0A\09mov ${0:B}, r0\0A\09", "=r,=z,1,~{r0}"(i16 %7) #1, !srcloc !4
    %asmresult27 = extractvalue { i16, i16 } %8, 0
    %9 = inttoptr i16 %asmresult27 to i8*
    switch i8 %mode, label %if.else.57 [
    i8 0, label %if.then.33
    i8 2, label %if.then.46
    ]

    if.then.33: ; preds = %if.end
    %10 = load volatile i8, i8* inttoptr (i16 95 to i8*), align 1, !tbaa !5
    tail call void asm sideeffect "cli", "~{memory}"() #1, !srcloc !8
    %conv35 = zext i8 %1 to i16
    %neg = xor i16 %conv35, -1
    %11 = load volatile i8, i8* %6, align 1, !tbaa !5
    %conv36 = zext i8 %11 to i16
    %and = and i16 %conv36, %neg
    %conv37 = trunc i16 %and to i8
    store volatile i8 %conv37, i8* %6, align 1, !tbaa !5
    %12 = load volatile i8, i8* %9, align 1, !tbaa !5
    %conv40 = zext i8 %12 to i16
    %and41 = and i16 %conv40, %neg
    %conv42 = trunc i16 %and41 to i8
    store volatile i8 %conv42, i8* %9, align 1, !tbaa !5
    store volatile i8 %10, i8* inttoptr (i16 95 to i8*), align 1, !tbaa !5
    br label %cleanup

    if.then.46: ; preds = %if.end
    %13 = load volatile i8, i8* inttoptr (i16 95 to i8*), align 1, !tbaa !5
    tail call void asm sideeffect "cli", "~{memory}"() #1, !srcloc !9
    %neg50 = xor i8 %1, -1
    %14 = load volatile i8, i8* %6, align 1, !tbaa !5
    %and52 = and i8 %14, %neg50
    store volatile i8 %and52, i8* %6, align 1, !tbaa !5
    %15 = load volatile i8, i8* %9, align 1, !tbaa !5
    %or89 = or i8 %15, %1
    store volatile i8 %or89, i8* %9, align 1, !tbaa !5
    store volatile i8 %13, i8* inttoptr (i16 95 to i8*), align 1, !tbaa !5
    br label %cleanup

    if.else.57: ; preds = %if.end
    %16 = load volatile i8, i8* inttoptr (i16 95 to i8*), align 1, !tbaa !5
    tail call void asm sideeffect "cli", "~{memory}"() #1, !srcloc !10
    %17 = load volatile i8, i8* %6, align 1, !tbaa !5
    %or6288 = or i8 %17, %1
    store volatile i8 %or6288, i8* %6, align 1, !tbaa !5
    store volatile i8 %16, i8* inttoptr (i16 95 to i8*), align 1, !tbaa !5
    br label %cleanup

    cleanup: ; preds = %if.then.33, %if.else.57, %if.then.46, %entry
    ret void
    }

    ; Function Attrs: nounwind
    define void @digitalWrite(i8 zeroext %pin, i8 zeroext %val) #0 {
    entry:
    %conv = zext i8 %pin to i16
    %add.ptr = getelementptr inbounds [20 x i8], [20 x i8]* @digital_pin_to_timer_PGM, i16 0, i16 %conv
    %0 = ptrtoint i8* %add.ptr to i16
    %1 = tail call i8 asm sideeffect "lpm\0A\09mov $0, r0\0A\09", "=r,z,~{r0}"(i16 %0) #1, !srcloc !11
    %add.ptr5 = getelementptr inbounds [20 x i8], [20 x i8]* @digital_pin_to_bit_mask_PGM, i16 0, i16 %conv
    %2 = ptrtoint i8* %add.ptr5 to i16
    %3 = tail call i8 asm sideeffect "lpm\0A\09mov $0, r0\0A\09", "=r,z,~{r0}"(i16 %2) #1, !srcloc !12
    %add.ptr13 = getelementptr inbounds [20 x i8], [20 x i8]* @digital_pin_to_port_PGM, i16 0, i16 %conv
    %4 = ptrtoint i8* %add.ptr13 to i16
    %5 = tail call i8 asm sideeffect "lpm\0A\09mov $0, r0\0A\09", "=r,z,~{r0}"(i16 %4) #1, !srcloc !13
    %conv18 = zext i8 %5 to i16
    %cmp = icmp eq i8 %5, 0
    br i1 %cmp, label %cleanup, label %if.end

    if.end: ; preds = %entry
    switch i8 %1, label %if.end.24 [
    i8 8, label %sw.bb.19.i
    i8 3, label %sw.bb.i
    i8 4, label %sw.bb.3.i
    i8 1, label %sw.bb.7.i
    i8 2, label %sw.bb.11.i
    i8 7, label %sw.bb.15.i
    ]

    sw.bb.i: ; preds = %if.end
    %6 = load volatile i8, i8* inttoptr (i16 128 to i8*), align 128, !tbaa !5
    %and.i = and i8 %6, 127
    store volatile i8 %and.i, i8* inttoptr (i16 128 to i8*), align 128, !tbaa !5
    br label %if.end.24

    sw.bb.3.i: ; preds = %if.end
    %7 = load volatile i8, i8* inttoptr (i16 128 to i8*), align 128, !tbaa !5
    %and5.i = and i8 %7, -33
    store volatile i8 %and5.i, i8* inttoptr (i16 128 to i8*), align 128, !tbaa !5
    br label %if.end.24

    sw.bb.7.i: ; preds = %if.end
    %8 = load volatile i8, i8* inttoptr (i16 68 to i8*), align 4, !tbaa !5
    %and9.i = and i8 %8, 127
    store volatile i8 %and9.i, i8* inttoptr (i16 68 to i8*), align 4, !tbaa !5
    br label %if.end.24

    sw.bb.11.i: ; preds = %if.end
    %9 = load volatile i8, i8* inttoptr (i16 68 to i8*), align 4, !tbaa !5
    %and13.i = and i8 %9, -33
    store volatile i8 %and13.i, i8* inttoptr (i16 68 to i8*), align 4, !tbaa !5
    br label %if.end.24

    sw.bb.15.i: ; preds = %if.end
    %10 = load volatile i8, i8* inttoptr (i16 176 to i8*), align 16, !tbaa !5
    %and17.i = and i8 %10, 127
    store volatile i8 %and17.i, i8* inttoptr (i16 176 to i8*), align 16, !tbaa !5
    br label %if.end.24

    sw.bb.19.i: ; preds = %if.end
    %11 = load volatile i8, i8* inttoptr (i16 176 to i8*), align 16, !tbaa !5
    %and21.i = and i8 %11, -33
    store volatile i8 %and21.i, i8* inttoptr (i16 176 to i8*), align 16, !tbaa !5
    br label %if.end.24

    if.end.24: ; preds = %if.end, %sw.bb.19.i, %sw.bb.15.i, %sw.bb.11.i, %sw.bb.7.i, %sw.bb.3.i, %sw.bb.i
    %add.ptr28 = getelementptr inbounds [5 x i16], [5 x i16]* @port_to_output_PGM, i16 0, i16 %conv18
    %12 = ptrtoint i16* %add.ptr28 to i16
    %13 = tail call { i16, i16 } asm sideeffect "lpm\0A\09mov ${0:A}, r0\0A\09adiw r30, 1\0A\09lpm\0A\09mov ${0:B}, r0\0A\09", "=r,=z,1,~{r0}"(i16 %12) #1, !srcloc !14
    %asmresult = extractvalue { i16, i16 } %13, 0
    %14 = inttoptr i16 %asmresult to i8*
    %15 = load volatile i8, i8* inttoptr (i16 95 to i8*), align 1, !tbaa !5
    tail call void asm sideeffect "cli", "~{memory}"() #1, !srcloc !15
    %cmp35 = icmp eq i8 %val, 0
    br i1 %cmp35, label %if.then.37, label %if.else

    if.then.37: ; preds = %if.end.24
    %neg = xor i8 %3, -1
    %16 = load volatile i8, i8* %14, align 1, !tbaa !5
    %and = and i8 %16, %neg
    store volatile i8 %and, i8* %14, align 1, !tbaa !5
    br label %if.end.44

    if.else: ; preds = %if.end.24
    %17 = load volatile i8, i8* %14, align 1, !tbaa !5
    %or59 = or i8 %17, %3
    store volatile i8 %or59, i8* %14, align 1, !tbaa !5
    br label %if.end.44

    if.end.44: ; preds = %if.else, %if.then.37
    store volatile i8 %15, i8* inttoptr (i16 95 to i8*), align 1, !tbaa !5
    br label %cleanup

    cleanup: ; preds = %entry, %if.end.44
    ret void
    }

    ; Function Attrs: nounwind
    define i16 @digitalRead(i8 zeroext %pin) #0 {
    entry:
    %conv = zext i8 %pin to i16
    %add.ptr = getelementptr inbounds [20 x i8], [20 x i8]* @digital_pin_to_timer_PGM, i16 0, i16 %conv
    %0 = ptrtoint i8* %add.ptr to i16
    %1 = tail call i8 asm sideeffect "lpm\0A\09mov $0, r0\0A\09", "=r,z,~{r0}"(i16 %0) #1, !srcloc !16
    %add.ptr5 = getelementptr inbounds [20 x i8], [20 x i8]* @digital_pin_to_bit_mask_PGM, i16 0, i16 %conv
    %2 = ptrtoint i8* %add.ptr5 to i16
    %3 = tail call i8 asm sideeffect "lpm\0A\09mov $0, r0\0A\09", "=r,z,~{r0}"(i16 %2) #1, !srcloc !17
    %add.ptr13 = getelementptr inbounds [20 x i8], [20 x i8]* @digital_pin_to_port_PGM, i16 0, i16 %conv
    %4 = ptrtoint i8* %add.ptr13 to i16
    %5 = tail call i8 asm sideeffect "lpm\0A\09mov $0, r0\0A\09", "=r,z,~{r0}"(i16 %4) #1, !srcloc !18
    %conv17 = zext i8 %5 to i16
    %cmp = icmp eq i8 %5, 0
    br i1 %cmp, label %cleanup, label %if.end

    if.end: ; preds = %entry
    switch i8 %1, label %if.end.23 [
    i8 8, label %sw.bb.19.i
    i8 3, label %sw.bb.i
    i8 4, label %sw.bb.3.i
    i8 1, label %sw.bb.7.i
    i8 2, label %sw.bb.11.i
    i8 7, label %sw.bb.15.i
    ]

    sw.bb.i: ; preds = %if.end
    %6 = load volatile i8, i8* inttoptr (i16 128 to i8*), align 128, !tbaa !5
    %and.i = and i8 %6, 127
    store volatile i8 %and.i, i8* inttoptr (i16 128 to i8*), align 128, !tbaa !5
    br label %if.end.23

    sw.bb.3.i: ; preds = %if.end
    %7 = load volatile i8, i8* inttoptr (i16 128 to i8*), align 128, !tbaa !5
    %and5.i = and i8 %7, -33
    store volatile i8 %and5.i, i8* inttoptr (i16 128 to i8*), align 128, !tbaa !5
    br label %if.end.23

    sw.bb.7.i: ; preds = %if.end
    %8 = load volatile i8, i8* inttoptr (i16 68 to i8*), align 4, !tbaa !5
    %and9.i = and i8 %8, 127
    store volatile i8 %and9.i, i8* inttoptr (i16 68 to i8*), align 4, !tbaa !5
    br label %if.end.23

    sw.bb.11.i: ; preds = %if.end
    %9 = load volatile i8, i8* inttoptr (i16 68 to i8*), align 4, !tbaa !5
    %and13.i = and i8 %9, -33
    store volatile i8 %and13.i, i8* inttoptr (i16 68 to i8*), align 4, !tbaa !5
    br label %if.end.23

    sw.bb.15.i: ; preds = %if.end
    %10 = load volatile i8, i8* inttoptr (i16 176 to i8*), align 16, !tbaa !5
    %and17.i = and i8 %10, 127
    store volatile i8 %and17.i, i8* inttoptr (i16 176 to i8*), align 16, !tbaa !5
    br label %if.end.23

    sw.bb.19.i: ; preds = %if.end
    %11 = load volatile i8, i8* inttoptr (i16 176 to i8*), align 16, !tbaa !5
    %and21.i = and i8 %11, -33
    store volatile i8 %and21.i, i8* inttoptr (i16 176 to i8*), align 16, !tbaa !5
    br label %if.end.23

    if.end.23: ; preds = %if.end, %sw.bb.19.i, %sw.bb.15.i, %sw.bb.11.i, %sw.bb.7.i, %sw.bb.3.i, %sw.bb.i
    %add.ptr27 = getelementptr inbounds [5 x i16], [5 x i16]* @port_to_input_PGM, i16 0, i16 %conv17
    %12 = ptrtoint i16* %add.ptr27 to i16
    %13 = tail call { i16, i16 } asm sideeffect "lpm\0A\09mov ${0:A}, r0\0A\09adiw r30, 1\0A\09lpm\0A\09mov ${0:B}, r0\0A\09", "=r,=z,1,~{r0}"(i16 %12) #1, !srcloc !19
    %asmresult = extractvalue { i16, i16 } %13, 0
    %14 = inttoptr i16 %asmresult to i8*
    %15 = load volatile i8, i8* %14, align 1, !tbaa !5
    %and47 = and i8 %15, %3
    %not.tobool = icmp ne i8 %and47, 0
    %. = zext i1 %not.tobool to i16
    br label %cleanup

    cleanup: ; preds = %if.end.23, %entry
    %retval.0 = phi i16 [ 0, %entry ], [ %., %if.end.23 ]
    ret i16 %retval.0
    }

    attributes #0 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #1 = { nounwind }

    !llvm.ident = !{!0}

    !0 = !{!"clang version 3.7.0 (https://github.com/llvm-mirror/clang.git 287e62c84a1ccd74fbca46bfc13e364e314d4b41) (https://github.com/llvm-mirror/llvm.git aaab572fc38b4438e769e2fd6b91963be11db7b2)"}
    !1 = !{i32 -2147151874, i32 -2147151865, i32 -2147151824}
    !2 = !{i32 -2147151084, i32 -2147151075, i32 -2147151034}
    !3 = !{i32 -2147150238, i32 -2147150219, i32 -2147150173, i32 -2147150127, i32 -2147150081, i32 -2147150035}
    !4 = !{i32 -2147149170, i32 -2147149151, i32 -2147149105, i32 -2147149059, i32 -2147149013, i32 -2147148967}
    !5 = !{!6, !6, i64 0}
    !6 = !{!"omnipotent char", !7, i64 0}
    !7 = !{!"Simple C/C++ TBAA"}
    !8 = !{i32 -2147148487}
    !9 = !{i32 -2147148169}
    !10 = !{i32 -2147147855}
    !11 = !{i32 -2147143912, i32 -2147143903, i32 -2147143862}
    !12 = !{i32 -2147143109, i32 -2147143100, i32 -2147143059}
    !13 = !{i32 -2147142319, i32 -2147142310, i32 -2147142269}
    !14 = !{i32 -2147141463, i32 -2147141444, i32 -2147141398, i32 -2147141352, i32 -2147141306, i32 -2147141260}
    !15 = !{i32 -2147140784}
    !16 = !{i32 -2147140137, i32 -2147140128, i32 -2147140087}
    !17 = !{i32 -2147139334, i32 -2147139325, i32 -2147139284}
    !18 = !{i32 -2147138544, i32 -2147138535, i32 -2147138494}
    !19 = !{i32 -2147137688, i32 -2147137669, i32 -2147137623, i32 -2147137577, i32 -2147137531, i32 -2147137485}
    130 changes: 130 additions & 0 deletions wiring_pulse.ll
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,130 @@
    ; ModuleID = './wiring_pulse.c'
    target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-i64:8:8-f32:8:8-f64:8:8-n8"
    target triple = "avr"

    @digital_pin_to_bit_mask_PGM = external constant [0 x i8], align 1
    @digital_pin_to_port_PGM = external constant [0 x i8], align 1
    @port_to_input_PGM = external constant [0 x i16], align 2

    ; Function Attrs: nounwind
    define i32 @pulseIn(i8 zeroext %pin, i8 zeroext %state, i32 %timeout) #0 {
    entry:
    %conv = zext i8 %pin to i16
    %add.ptr = getelementptr inbounds [0 x i8], [0 x i8]* @digital_pin_to_bit_mask_PGM, i16 0, i16 %conv
    %0 = ptrtoint i8* %add.ptr to i16
    %1 = tail call i8 asm sideeffect "lpm\0A\09mov $0, r0\0A\09", "=r,z,~{r0}"(i16 %0) #1, !srcloc !1
    %add.ptr5 = getelementptr inbounds [0 x i8], [0 x i8]* @digital_pin_to_port_PGM, i16 0, i16 %conv
    %2 = ptrtoint i8* %add.ptr5 to i16
    %3 = tail call i8 asm sideeffect "lpm\0A\09mov $0, r0\0A\09", "=r,z,~{r0}"(i16 %2) #1, !srcloc !2
    %tobool = icmp ne i8 %state, 0
    %mul = and i32 %timeout, 268435455
    %conv18 = zext i8 %3 to i16
    %add.ptr19 = getelementptr inbounds [0 x i16], [0 x i16]* @port_to_input_PGM, i16 0, i16 %conv18
    %4 = ptrtoint i16* %add.ptr19 to i16
    %5 = zext i8 %1 to i16
    %conv26 = select i1 %tobool, i16 %5, i16 0
    br label %while.cond

    while.cond: ; preds = %while.body, %entry
    %numloops.0 = phi i32 [ 0, %entry ], [ %inc, %while.body ]
    %6 = tail call { i16, i16 } asm sideeffect "lpm\0A\09mov ${0:A}, r0\0A\09adiw r30, 1\0A\09lpm\0A\09mov ${0:B}, r0\0A\09", "=r,=z,1,~{r0}"(i16 %4) #1, !srcloc !3
    %asmresult = extractvalue { i16, i16 } %6, 0
    %7 = inttoptr i16 %asmresult to i8*
    %8 = load volatile i8, i8* %7, align 1, !tbaa !4
    %and108 = and i8 %8, %1
    %and = zext i8 %and108 to i16
    %cmp = icmp eq i16 %and, %conv26
    br i1 %cmp, label %while.body, label %while.cond.30.preheader

    while.cond.30.preheader: ; preds = %while.cond
    %numloops.0.lcssa = phi i32 [ %numloops.0, %while.cond ]
    br label %while.cond.30

    while.body: ; preds = %while.cond
    %inc = add i32 %numloops.0, 1
    %cmp28 = icmp eq i32 %numloops.0, %mul
    br i1 %cmp28, label %cleanup.loopexit137, label %while.cond

    while.cond.30: ; preds = %while.cond.30.preheader, %while.body.46
    %numloops.1 = phi i32 [ %inc47, %while.body.46 ], [ %numloops.0.lcssa, %while.cond.30.preheader ]
    %9 = tail call { i16, i16 } asm sideeffect "lpm\0A\09mov ${0:A}, r0\0A\09adiw r30, 1\0A\09lpm\0A\09mov ${0:B}, r0\0A\09", "=r,=z,1,~{r0}"(i16 %4) #1, !srcloc !7
    %asmresult37 = extractvalue { i16, i16 } %9, 0
    %10 = inttoptr i16 %asmresult37 to i8*
    %11 = load volatile i8, i8* %10, align 1, !tbaa !4
    %and42109 = and i8 %11, %1
    %and42 = zext i8 %and42109 to i16
    %cmp44 = icmp eq i16 %and42, %conv26
    br i1 %cmp44, label %while.cond.53.preheader, label %while.body.46

    while.cond.53.preheader: ; preds = %while.cond.30
    %numloops.1.lcssa = phi i32 [ %numloops.1, %while.cond.30 ]
    %12 = tail call { i16, i16 } asm sideeffect "lpm\0A\09mov ${0:A}, r0\0A\09adiw r30, 1\0A\09lpm\0A\09mov ${0:B}, r0\0A\09", "=r,=z,1,~{r0}"(i16 %4) #1, !srcloc !8
    %asmresult60.118 = extractvalue { i16, i16 } %12, 0
    %13 = inttoptr i16 %asmresult60.118 to i8*
    %14 = load volatile i8, i8* %13, align 1, !tbaa !4
    %and65110.119 = and i8 %14, %1
    %and65.120 = zext i8 %and65110.119 to i16
    %cmp67.121 = icmp eq i16 %and65.120, %conv26
    br i1 %cmp67.121, label %while.body.69.preheader, label %cleanup

    while.body.69.preheader: ; preds = %while.cond.53.preheader
    br label %while.body.69

    while.body.46: ; preds = %while.cond.30
    %inc47 = add i32 %numloops.1, 1
    %cmp48 = icmp eq i32 %numloops.1, %mul
    br i1 %cmp48, label %cleanup.loopexit136, label %while.cond.30

    while.body.69: ; preds = %while.body.69.preheader, %if.end.74
    %width.0123 = phi i32 [ %inc75, %if.end.74 ], [ 0, %while.body.69.preheader ]
    %numloops.2122 = phi i32 [ %inc70, %if.end.74 ], [ %numloops.1.lcssa, %while.body.69.preheader ]
    %cmp71 = icmp eq i32 %numloops.2122, %mul
    br i1 %cmp71, label %cleanup.loopexit, label %if.end.74

    if.end.74: ; preds = %while.body.69
    %inc70 = add i32 %numloops.2122, 1
    %inc75 = add i32 %width.0123, 1
    %15 = tail call { i16, i16 } asm sideeffect "lpm\0A\09mov ${0:A}, r0\0A\09adiw r30, 1\0A\09lpm\0A\09mov ${0:B}, r0\0A\09", "=r,=z,1,~{r0}"(i16 %4) #1, !srcloc !8
    %asmresult60 = extractvalue { i16, i16 } %15, 0
    %16 = inttoptr i16 %asmresult60 to i8*
    %17 = load volatile i8, i8* %16, align 1, !tbaa !4
    %and65110 = and i8 %17, %1
    %and65 = zext i8 %and65110 to i16
    %cmp67 = icmp eq i16 %and65, %conv26
    br i1 %cmp67, label %while.body.69, label %while.cond.53.while.end.76_crit_edge

    while.cond.53.while.end.76_crit_edge: ; preds = %if.end.74
    %inc75.lcssa = phi i32 [ %inc75, %if.end.74 ]
    %phitmp = mul i32 %inc75.lcssa, 21
    %phitmp124 = add i32 %phitmp, 16
    %phitmp125 = lshr i32 %phitmp124, 4
    br label %cleanup

    cleanup.loopexit: ; preds = %while.body.69
    br label %cleanup

    cleanup.loopexit136: ; preds = %while.body.46
    br label %cleanup

    cleanup.loopexit137: ; preds = %while.body
    br label %cleanup

    cleanup: ; preds = %cleanup.loopexit137, %cleanup.loopexit136, %cleanup.loopexit, %while.cond.53.preheader, %while.cond.53.while.end.76_crit_edge
    %retval.0 = phi i32 [ %phitmp125, %while.cond.53.while.end.76_crit_edge ], [ 1, %while.cond.53.preheader ], [ 0, %cleanup.loopexit ], [ 0, %cleanup.loopexit136 ], [ 0, %cleanup.loopexit137 ]
    ret i32 %retval.0
    }

    attributes #0 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #1 = { nounwind }

    !llvm.ident = !{!0}

    !0 = !{!"clang version 3.7.0 (https://github.com/llvm-mirror/clang.git 287e62c84a1ccd74fbca46bfc13e364e314d4b41) (https://github.com/llvm-mirror/llvm.git aaab572fc38b4438e769e2fd6b91963be11db7b2)"}
    !1 = !{i32 -2147155654, i32 -2147155645, i32 -2147155604}
    !2 = !{i32 -2147154864, i32 -2147154855, i32 -2147154814}
    !3 = !{i32 -2147153940, i32 -2147153921, i32 -2147153875, i32 -2147153829, i32 -2147153783, i32 -2147153737}
    !4 = !{!5, !5, i64 0}
    !5 = !{!"omnipotent char", !6, i64 0}
    !6 = !{!"Simple C/C++ TBAA"}
    !7 = !{i32 -2147152875, i32 -2147152856, i32 -2147152810, i32 -2147152764, i32 -2147152718, i32 -2147152672}
    !8 = !{i32 -2147151810, i32 -2147151791, i32 -2147151745, i32 -2147151699, i32 -2147151653, i32 -2147151607}
    98 changes: 98 additions & 0 deletions wiring_shift.ll
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,98 @@
    ; ModuleID = './wiring_shift.c'
    target datalayout = "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-i64:8:8-f32:8:8-f64:8:8-n8"
    target triple = "avr"

    ; Function Attrs: nounwind
    define zeroext i8 @shiftIn(i8 zeroext %dataPin, i8 zeroext %clockPin, i8 zeroext %bitOrder) #0 {
    entry:
    %cmp3 = icmp eq i8 %bitOrder, 0
    br label %for.body

    for.body: ; preds = %if.end, %entry
    %conv22 = phi i16 [ 0, %entry ], [ %conv, %if.end ]
    %i.021 = phi i8 [ 0, %entry ], [ %inc, %if.end ]
    %value.020 = phi i8 [ 0, %entry ], [ %or.sink.off0, %if.end ]
    tail call void @digitalWrite(i8 zeroext %clockPin, i8 zeroext 1) #2
    %call = tail call i16 @digitalRead(i8 zeroext %dataPin) #2
    br i1 %cmp3, label %if.then, label %if.else

    if.then: ; preds = %for.body
    %shl = shl i16 %call, %conv22
    %conv6 = zext i8 %value.020 to i16
    %or = or i16 %shl, %conv6
    %extract.t26 = trunc i16 %or to i8
    br label %if.end

    if.else: ; preds = %for.body
    %sub = sub nuw nsw i16 7, %conv22
    %shl10 = shl i16 %call, %sub
    %conv11 = zext i8 %value.020 to i16
    %or12 = or i16 %shl10, %conv11
    %extract.t27 = trunc i16 %or12 to i8
    br label %if.end

    if.end: ; preds = %if.else, %if.then
    %or.sink.off0 = phi i8 [ %extract.t26, %if.then ], [ %extract.t27, %if.else ]
    tail call void @digitalWrite(i8 zeroext %clockPin, i8 zeroext 0) #2
    %inc = add nuw nsw i8 %i.021, 1
    %conv = zext i8 %inc to i16
    %exitcond = icmp eq i8 %inc, 8
    br i1 %exitcond, label %for.end, label %for.body

    for.end: ; preds = %if.end
    %or.sink.off0.lcssa = phi i8 [ %or.sink.off0, %if.end ]
    ret i8 %or.sink.off0.lcssa
    }

    declare void @digitalWrite(i8 zeroext, i8 zeroext) #1

    declare i16 @digitalRead(i8 zeroext) #1

    ; Function Attrs: nounwind
    define void @shiftOut(i8 zeroext %dataPin, i8 zeroext %clockPin, i8 zeroext %bitOrder, i8 zeroext %val) #0 {
    entry:
    %cmp3 = icmp eq i8 %bitOrder, 0
    %conv5 = zext i8 %val to i16
    br label %for.body

    for.body: ; preds = %if.end, %entry
    %conv23 = phi i16 [ 0, %entry ], [ %conv, %if.end ]
    %i.022 = phi i8 [ 0, %entry ], [ %inc, %if.end ]
    br i1 %cmp3, label %if.then, label %if.else

    if.then: ; preds = %for.body
    %shl = shl i16 1, %conv23
    %and = and i16 %shl, %conv5
    %tobool = icmp ne i16 %and, 0
    %conv8 = zext i1 %tobool to i8
    tail call void @digitalWrite(i8 zeroext %dataPin, i8 zeroext %conv8) #2
    br label %if.end

    if.else: ; preds = %for.body
    %sub = sub nuw nsw i16 7, %conv23
    %shl11 = shl i16 1, %sub
    %and12 = and i16 %shl11, %conv5
    %tobool13 = icmp ne i16 %and12, 0
    %conv18 = zext i1 %tobool13 to i8
    tail call void @digitalWrite(i8 zeroext %dataPin, i8 zeroext %conv18) #2
    br label %if.end

    if.end: ; preds = %if.else, %if.then
    tail call void @digitalWrite(i8 zeroext %clockPin, i8 zeroext 1) #2
    tail call void @digitalWrite(i8 zeroext %clockPin, i8 zeroext 0) #2
    %inc = add nuw nsw i8 %i.022, 1
    %conv = zext i8 %inc to i16
    %exitcond = icmp eq i8 %inc, 8
    br i1 %exitcond, label %for.end, label %for.body

    for.end: ; preds = %if.end
    ret void
    }

    attributes #0 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #1 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="atmega328p" "unsafe-fp-math"="false" "use-soft-float"="false" }
    attributes #2 = { nounwind }

    !llvm.ident = !{!0}

    !0 = !{!"clang version 3.7.0 (https://github.com/llvm-mirror/clang.git 287e62c84a1ccd74fbca46bfc13e364e314d4b41) (https://github.com/llvm-mirror/llvm.git aaab572fc38b4438e769e2fd6b91963be11db7b2)"}
  9. Dylan McKay created this gist Jul 8, 2015.
    14 changes: 14 additions & 0 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,14 @@
    Here is the Arduino core compiled into LLVM IR files

    They were generated using:
    ``` bash
    for file in $(find -name "*.cpp"); do
    clang++ $file -I ./ -I ../../variants/standard/ -o ~/Ard/$(basename $file .cpp).ll \
    -c --target=avr -I /usr/avr/include -S -emit-llvm -mcpu=atmega328p -DF_CPU=16000000 -O
    done

    for file in $(find -name "*.c"); do
    clang $file -I ./ -I ../../variants/standard/ -o ~/Ard/$(basename $file .c).ll \
    -c --target=avr -I /usr/avr/include -S -emit-llvm -mcpu=atmega328p -DF_CPU=16000000 -O
    done
    ```