632 lines
13 KiB
LLVM
632 lines
13 KiB
LLVM
; Pin: an i32 compare lowers to the 65xx multi-precision compare, not to
|
|
; materialised per-half booleans.
|
|
;
|
|
; Ordered predicates: lda lhs.lo ; cmp rhs.lo ; lda lhs.hi ; sbc rhs.hi
|
|
; then ONE bcc/bcs (or one SELECT_CC diamond for a value). The CMP leaves
|
|
; C = no-borrow of the low halves, the SBC folds it into the high halves.
|
|
; Signed predicates first bias both high halves by 0x8000 (a constant's
|
|
; bias folds: 0x1234 -> sbc #0x9234). x <= K / x > K become x < K+1 /
|
|
; x >= K+1; reg/reg <= and > swap operands. A constant whose low half is
|
|
; 0 reduces to an i16 compare of the high halves (x < 0x10000 is hi < 1,
|
|
; signed x < 0 is hi < 0, which is just `lda hi ; bmi`).
|
|
;
|
|
; eq / ne feeding a branch (W65816CmpPrepare): the low halves, bne, then
|
|
; the high halves, bne. Against 0 (or a constant with a zero half) it stays
|
|
; the branch-free lo | hi, (lo ^ K) | hi, ... tested against 0.
|
|
;
|
|
; The old lowering built (hiLT | (hiEQ & loLT)) from three i16 setcc
|
|
; diamonds and branched on the OR: every `i < n` in a 32-bit loop paid for
|
|
; three materialised booleans and a PHP/PLP. CHECK-NOT php pins that.
|
|
;
|
|
; RUN: llc -mtriple=w65816 -O2 < %s | FileCheck %s
|
|
|
|
target datalayout = "e-m:e-p:32:16-i16:16-i32:16-i64:16-f32:16-f64:16-a:8-n8:16-S16"
|
|
|
|
@sink = global i16 0
|
|
|
|
; a.hi arrives in X: it must be loaded into A for the second compare.
|
|
define void @br_eq(i32 %a, i32 %b) {
|
|
; CHECK-LABEL: br_eq:
|
|
; CHECK-NOT: php
|
|
; CHECK: stx 0xd0
|
|
; CHECK-NEXT: cmp 0x4, s
|
|
; CHECK-NEXT: bne [[F:.LBB[0-9_]+]]
|
|
; CHECK: lda 0xd0
|
|
; CHECK-NEXT: cmp 0x6, s
|
|
; CHECK-NEXT: bne [[F]]
|
|
; CHECK: rtl
|
|
entry:
|
|
%c = icmp eq i32 %a, %b
|
|
br i1 %c, label %t, label %f
|
|
t:
|
|
store volatile i16 1, ptr @sink
|
|
ret void
|
|
f:
|
|
store volatile i16 2, ptr @sink
|
|
ret void
|
|
}
|
|
|
|
define void @br_ne(i32 %a, i32 %b) {
|
|
; CHECK-LABEL: br_ne:
|
|
; CHECK-NOT: php
|
|
; CHECK: stx 0xd0
|
|
; CHECK-NEXT: cmp 0x4, s
|
|
; CHECK-NEXT: bne [[T:.LBB[0-9_]+]]
|
|
; CHECK: lda 0xd0
|
|
; CHECK-NEXT: cmp 0x6, s
|
|
; CHECK-NEXT: bne [[T]]
|
|
; CHECK: rtl
|
|
entry:
|
|
%c = icmp ne i32 %a, %b
|
|
br i1 %c, label %t, label %f
|
|
t:
|
|
store volatile i16 1, ptr @sink
|
|
ret void
|
|
f:
|
|
store volatile i16 2, ptr @sink
|
|
ret void
|
|
}
|
|
|
|
; a.lo arrives in A, a.hi in X, b on the stack.
|
|
define void @br_ult(i32 %a, i32 %b) {
|
|
; CHECK-LABEL: br_ult:
|
|
; CHECK-NOT: php
|
|
; CHECK: stx 0xd0
|
|
; CHECK-NEXT: cmp 0x4, s
|
|
; CHECK-NEXT: lda 0xd0
|
|
; CHECK-NEXT: sbc 0x6, s
|
|
; CHECK-NEXT: bcs
|
|
; CHECK: rtl
|
|
entry:
|
|
%c = icmp ult i32 %a, %b
|
|
br i1 %c, label %t, label %f
|
|
t:
|
|
store volatile i16 1, ptr @sink
|
|
ret void
|
|
f:
|
|
store volatile i16 2, ptr @sink
|
|
ret void
|
|
}
|
|
|
|
; a <= b is b >= a: b is loaded first.
|
|
define void @br_ule(i32 %a, i32 %b) {
|
|
; CHECK-LABEL: br_ule:
|
|
; CHECK-NOT: php
|
|
; CHECK: lda 0x8, s
|
|
; CHECK-NEXT: cmp 0x1, s
|
|
; CHECK: lda 0xa, s
|
|
; CHECK-NEXT: sbc 0x3, s
|
|
; CHECK-NEXT: bcc
|
|
; CHECK: rtl
|
|
entry:
|
|
%c = icmp ule i32 %a, %b
|
|
br i1 %c, label %t, label %f
|
|
t:
|
|
store volatile i16 1, ptr @sink
|
|
ret void
|
|
f:
|
|
store volatile i16 2, ptr @sink
|
|
ret void
|
|
}
|
|
|
|
define void @br_ugt(i32 %a, i32 %b) {
|
|
; CHECK-LABEL: br_ugt:
|
|
; CHECK-NOT: php
|
|
; CHECK: lda 0x8, s
|
|
; CHECK-NEXT: cmp 0x1, s
|
|
; CHECK: lda 0xa, s
|
|
; CHECK-NEXT: sbc 0x3, s
|
|
; CHECK-NEXT: bcs
|
|
; CHECK: rtl
|
|
entry:
|
|
%c = icmp ugt i32 %a, %b
|
|
br i1 %c, label %t, label %f
|
|
t:
|
|
store volatile i16 1, ptr @sink
|
|
ret void
|
|
f:
|
|
store volatile i16 2, ptr @sink
|
|
ret void
|
|
}
|
|
|
|
define void @br_uge(i32 %a, i32 %b) {
|
|
; CHECK-LABEL: br_uge:
|
|
; CHECK-NOT: php
|
|
; CHECK: stx 0xd0
|
|
; CHECK-NEXT: cmp 0x4, s
|
|
; CHECK-NEXT: lda 0xd0
|
|
; CHECK-NEXT: sbc 0x6, s
|
|
; CHECK-NEXT: bcc
|
|
; CHECK: rtl
|
|
entry:
|
|
%c = icmp uge i32 %a, %b
|
|
br i1 %c, label %t, label %f
|
|
t:
|
|
store volatile i16 1, ptr @sink
|
|
ret void
|
|
f:
|
|
store volatile i16 2, ptr @sink
|
|
ret void
|
|
}
|
|
|
|
; Signed: both high halves biased by 0x8000, then the unsigned chain.
|
|
define void @br_slt(i32 %a, i32 %b) {
|
|
; CHECK-LABEL: br_slt:
|
|
; CHECK-NOT: php
|
|
; CHECK: eor
|
|
; CHECK: eor #0x8000
|
|
; CHECK: cmp 0xa, s
|
|
; CHECK-NEXT: lda
|
|
; CHECK-NEXT: sbc
|
|
; CHECK-NEXT: bcs
|
|
; CHECK: rtl
|
|
entry:
|
|
%c = icmp slt i32 %a, %b
|
|
br i1 %c, label %t, label %f
|
|
t:
|
|
store volatile i16 1, ptr @sink
|
|
ret void
|
|
f:
|
|
store volatile i16 2, ptr @sink
|
|
ret void
|
|
}
|
|
|
|
define void @br_sle(i32 %a, i32 %b) {
|
|
; CHECK-LABEL: br_sle:
|
|
; CHECK-NOT: php
|
|
; CHECK: eor #0x8000
|
|
; CHECK: eor
|
|
; CHECK: lda 0xa, s
|
|
; CHECK-NEXT: cmp
|
|
; CHECK-NEXT: lda
|
|
; CHECK-NEXT: sbc
|
|
; CHECK-NEXT: bcc
|
|
; CHECK: rtl
|
|
entry:
|
|
%c = icmp sle i32 %a, %b
|
|
br i1 %c, label %t, label %f
|
|
t:
|
|
store volatile i16 1, ptr @sink
|
|
ret void
|
|
f:
|
|
store volatile i16 2, ptr @sink
|
|
ret void
|
|
}
|
|
|
|
define void @br_sgt(i32 %a, i32 %b) {
|
|
; CHECK-LABEL: br_sgt:
|
|
; CHECK-NOT: php
|
|
; CHECK: eor #0x8000
|
|
; CHECK: eor
|
|
; CHECK: lda 0xa, s
|
|
; CHECK-NEXT: cmp
|
|
; CHECK-NEXT: lda
|
|
; CHECK-NEXT: sbc
|
|
; CHECK-NEXT: bcs
|
|
; CHECK: rtl
|
|
entry:
|
|
%c = icmp sgt i32 %a, %b
|
|
br i1 %c, label %t, label %f
|
|
t:
|
|
store volatile i16 1, ptr @sink
|
|
ret void
|
|
f:
|
|
store volatile i16 2, ptr @sink
|
|
ret void
|
|
}
|
|
|
|
define void @br_sge(i32 %a, i32 %b) {
|
|
; CHECK-LABEL: br_sge:
|
|
; CHECK-NOT: php
|
|
; CHECK: eor
|
|
; CHECK: eor #0x8000
|
|
; CHECK: cmp 0xa, s
|
|
; CHECK-NEXT: lda
|
|
; CHECK-NEXT: sbc
|
|
; CHECK-NEXT: bcc
|
|
; CHECK: rtl
|
|
entry:
|
|
%c = icmp sge i32 %a, %b
|
|
br i1 %c, label %t, label %f
|
|
t:
|
|
store volatile i16 1, ptr @sink
|
|
ret void
|
|
f:
|
|
store volatile i16 2, ptr @sink
|
|
ret void
|
|
}
|
|
|
|
; Against a constant (0x12345678): immediate operands, x <= K as x < K+1.
|
|
define void @brk_eq(i32 %a) {
|
|
; CHECK-LABEL: brk_eq:
|
|
; CHECK-NOT: php
|
|
; CHECK: cmp #0x5678
|
|
; CHECK-NEXT: bne [[F:.LBB[0-9_]+]]
|
|
; CHECK: lda 0xd0
|
|
; CHECK-NEXT: cmp #0x1234
|
|
; CHECK-NEXT: bne [[F]]
|
|
; CHECK: rtl
|
|
entry:
|
|
%c = icmp eq i32 %a, 305419896
|
|
br i1 %c, label %t, label %f
|
|
t:
|
|
store volatile i16 1, ptr @sink
|
|
ret void
|
|
f:
|
|
store volatile i16 2, ptr @sink
|
|
ret void
|
|
}
|
|
|
|
define void @brk_ne(i32 %a) {
|
|
; CHECK-LABEL: brk_ne:
|
|
; CHECK-NOT: php
|
|
; CHECK: cmp #0x5678
|
|
; CHECK-NEXT: bne [[T:.LBB[0-9_]+]]
|
|
; CHECK: lda 0xd0
|
|
; CHECK-NEXT: cmp #0x1234
|
|
; CHECK-NEXT: bne [[T]]
|
|
; CHECK: rtl
|
|
entry:
|
|
%c = icmp ne i32 %a, 305419896
|
|
br i1 %c, label %t, label %f
|
|
t:
|
|
store volatile i16 1, ptr @sink
|
|
ret void
|
|
f:
|
|
store volatile i16 2, ptr @sink
|
|
ret void
|
|
}
|
|
|
|
define void @brk_ult(i32 %a) {
|
|
; CHECK-LABEL: brk_ult:
|
|
; CHECK-NOT: php
|
|
; CHECK: cmp #0x5678
|
|
; CHECK-NEXT: lda 0xd0
|
|
; CHECK-NEXT: sbc #0x1234
|
|
; CHECK-NEXT: bcs
|
|
; CHECK: rtl
|
|
entry:
|
|
%c = icmp ult i32 %a, 305419896
|
|
br i1 %c, label %t, label %f
|
|
t:
|
|
store volatile i16 1, ptr @sink
|
|
ret void
|
|
f:
|
|
store volatile i16 2, ptr @sink
|
|
ret void
|
|
}
|
|
|
|
define void @brk_ule(i32 %a) {
|
|
; CHECK-LABEL: brk_ule:
|
|
; CHECK-NOT: php
|
|
; CHECK: cmp #0x5679
|
|
; CHECK-NEXT: lda 0xd0
|
|
; CHECK-NEXT: sbc #0x1234
|
|
; CHECK-NEXT: bcs
|
|
; CHECK: rtl
|
|
entry:
|
|
%c = icmp ule i32 %a, 305419896
|
|
br i1 %c, label %t, label %f
|
|
t:
|
|
store volatile i16 1, ptr @sink
|
|
ret void
|
|
f:
|
|
store volatile i16 2, ptr @sink
|
|
ret void
|
|
}
|
|
|
|
define void @brk_ugt(i32 %a) {
|
|
; CHECK-LABEL: brk_ugt:
|
|
; CHECK-NOT: php
|
|
; CHECK: cmp #0x5679
|
|
; CHECK-NEXT: lda 0xd0
|
|
; CHECK-NEXT: sbc #0x1234
|
|
; CHECK-NEXT: bcc
|
|
; CHECK: rtl
|
|
entry:
|
|
%c = icmp ugt i32 %a, 305419896
|
|
br i1 %c, label %t, label %f
|
|
t:
|
|
store volatile i16 1, ptr @sink
|
|
ret void
|
|
f:
|
|
store volatile i16 2, ptr @sink
|
|
ret void
|
|
}
|
|
|
|
define void @brk_uge(i32 %a) {
|
|
; CHECK-LABEL: brk_uge:
|
|
; CHECK-NOT: php
|
|
; CHECK: cmp #0x5678
|
|
; CHECK-NEXT: lda 0xd0
|
|
; CHECK-NEXT: sbc #0x1234
|
|
; CHECK-NEXT: bcc
|
|
; CHECK: rtl
|
|
entry:
|
|
%c = icmp uge i32 %a, 305419896
|
|
br i1 %c, label %t, label %f
|
|
t:
|
|
store volatile i16 1, ptr @sink
|
|
ret void
|
|
f:
|
|
store volatile i16 2, ptr @sink
|
|
ret void
|
|
}
|
|
|
|
define void @brk_slt(i32 %a) {
|
|
; CHECK-LABEL: brk_slt:
|
|
; CHECK-NOT: php
|
|
; CHECK: eor #0x8000
|
|
; CHECK: cmp #0x5678
|
|
; CHECK-NEXT: lda
|
|
; CHECK-NEXT: sbc #0x9234
|
|
; CHECK-NEXT: bcs
|
|
; CHECK: rtl
|
|
entry:
|
|
%c = icmp slt i32 %a, 305419896
|
|
br i1 %c, label %t, label %f
|
|
t:
|
|
store volatile i16 1, ptr @sink
|
|
ret void
|
|
f:
|
|
store volatile i16 2, ptr @sink
|
|
ret void
|
|
}
|
|
|
|
define void @brk_sle(i32 %a) {
|
|
; CHECK-LABEL: brk_sle:
|
|
; CHECK-NOT: php
|
|
; CHECK: eor #0x8000
|
|
; CHECK: cmp #0x5679
|
|
; CHECK-NEXT: lda
|
|
; CHECK-NEXT: sbc #0x9234
|
|
; CHECK-NEXT: bcs
|
|
; CHECK: rtl
|
|
entry:
|
|
%c = icmp sle i32 %a, 305419896
|
|
br i1 %c, label %t, label %f
|
|
t:
|
|
store volatile i16 1, ptr @sink
|
|
ret void
|
|
f:
|
|
store volatile i16 2, ptr @sink
|
|
ret void
|
|
}
|
|
|
|
define void @brk_sgt(i32 %a) {
|
|
; CHECK-LABEL: brk_sgt:
|
|
; CHECK-NOT: php
|
|
; CHECK: eor #0x8000
|
|
; CHECK: cmp #0x5679
|
|
; CHECK-NEXT: lda
|
|
; CHECK-NEXT: sbc #0x9234
|
|
; CHECK-NEXT: bcc
|
|
; CHECK: rtl
|
|
entry:
|
|
%c = icmp sgt i32 %a, 305419896
|
|
br i1 %c, label %t, label %f
|
|
t:
|
|
store volatile i16 1, ptr @sink
|
|
ret void
|
|
f:
|
|
store volatile i16 2, ptr @sink
|
|
ret void
|
|
}
|
|
|
|
define void @brk_sge(i32 %a) {
|
|
; CHECK-LABEL: brk_sge:
|
|
; CHECK-NOT: php
|
|
; CHECK: eor #0x8000
|
|
; CHECK: cmp #0x5678
|
|
; CHECK-NEXT: lda
|
|
; CHECK-NEXT: sbc #0x9234
|
|
; CHECK-NEXT: bcc
|
|
; CHECK: rtl
|
|
entry:
|
|
%c = icmp sge i32 %a, 305419896
|
|
br i1 %c, label %t, label %f
|
|
t:
|
|
store volatile i16 1, ptr @sink
|
|
ret void
|
|
f:
|
|
store volatile i16 2, ptr @sink
|
|
ret void
|
|
}
|
|
|
|
; Against 0 and -1, and constants whose low half is 0: no chain at all.
|
|
define void @brk_eq0(i32 %a) {
|
|
; CHECK-LABEL: brk_eq0:
|
|
; CHECK-NOT: eor
|
|
; CHECK: lda 0xd0
|
|
; CHECK-NEXT: ora 0x1, s
|
|
; CHECK-NEXT: beq
|
|
; CHECK: rtl
|
|
entry:
|
|
%c = icmp eq i32 %a, 0
|
|
br i1 %c, label %t, label %f
|
|
t:
|
|
store volatile i16 1, ptr @sink
|
|
ret void
|
|
f:
|
|
store volatile i16 2, ptr @sink
|
|
ret void
|
|
}
|
|
|
|
define void @brk_slt0(i32 %a) {
|
|
; CHECK-LABEL: brk_slt0:
|
|
; CHECK-NOT: sbc
|
|
; CHECK: lda 0xd0
|
|
; CHECK-NEXT: bmi
|
|
; CHECK: rtl
|
|
entry:
|
|
%c = icmp slt i32 %a, 0
|
|
br i1 %c, label %t, label %f
|
|
t:
|
|
store volatile i16 1, ptr @sink
|
|
ret void
|
|
f:
|
|
store volatile i16 2, ptr @sink
|
|
ret void
|
|
}
|
|
|
|
; x > -1 is x >= 0: the high half's sign alone.
|
|
define void @brk_sgtm1(i32 %a) {
|
|
; CHECK-LABEL: brk_sgtm1:
|
|
; CHECK-NOT: sbc
|
|
; CHECK: lda 0xd0
|
|
; CHECK-NEXT: bmi
|
|
; CHECK: rtl
|
|
entry:
|
|
%c = icmp sgt i32 %a, -1
|
|
br i1 %c, label %t, label %f
|
|
t:
|
|
store volatile i16 1, ptr @sink
|
|
ret void
|
|
f:
|
|
store volatile i16 2, ptr @sink
|
|
ret void
|
|
}
|
|
|
|
define void @brk_ult64k(i32 %a) {
|
|
; CHECK-LABEL: brk_ult64k:
|
|
; CHECK-NOT: sbc
|
|
; CHECK: lda 0xd0
|
|
; CHECK-NEXT: cmp #0x1
|
|
; CHECK-NEXT: bcs
|
|
; CHECK: rtl
|
|
entry:
|
|
%c = icmp ult i32 %a, 65536
|
|
br i1 %c, label %t, label %f
|
|
t:
|
|
store volatile i16 1, ptr @sink
|
|
ret void
|
|
f:
|
|
store volatile i16 2, ptr @sink
|
|
ret void
|
|
}
|
|
|
|
; x > 0x1FFFF is x >= 0x20000 is hi >= 2.
|
|
define void @brk_ugt1ffff(i32 %a) {
|
|
; CHECK-LABEL: brk_ugt1ffff:
|
|
; CHECK-NOT: sbc
|
|
; CHECK: lda 0xd0
|
|
; CHECK-NEXT: cmp #0x2
|
|
; CHECK-NEXT: bcc
|
|
; CHECK: rtl
|
|
entry:
|
|
%c = icmp ugt i32 %a, 131071
|
|
br i1 %c, label %t, label %f
|
|
t:
|
|
store volatile i16 1, ptr @sink
|
|
ret void
|
|
f:
|
|
store volatile i16 2, ptr @sink
|
|
ret void
|
|
}
|
|
|
|
; A value: one diamond on the chain's C, not three.
|
|
define i16 @set_ult(i32 %a, i32 %b) {
|
|
; CHECK-LABEL: set_ult:
|
|
; CHECK-NOT: php
|
|
; CHECK: cmp 0x4, s
|
|
; CHECK-NEXT: lda 0xd0
|
|
; CHECK-NEXT: sbc 0x6, s
|
|
; CHECK-NEXT: lda #0x1
|
|
; CHECK-NEXT: bcc
|
|
; CHECK: lda #0x0
|
|
; CHECK: rtl
|
|
entry:
|
|
%c = icmp ult i32 %a, %b
|
|
%z = zext i1 %c to i16
|
|
ret i16 %z
|
|
}
|
|
|
|
define i16 @set_sge(i32 %a, i32 %b) {
|
|
; CHECK-LABEL: set_sge:
|
|
; CHECK-NOT: php
|
|
; CHECK: cmp
|
|
; CHECK: sbc
|
|
; CHECK-NEXT: bcs
|
|
; CHECK: rtl
|
|
entry:
|
|
%c = icmp sge i32 %a, %b
|
|
%z = zext i1 %c to i16
|
|
ret i16 %z
|
|
}
|
|
|
|
; The combiner folds the zext into an i32-typed SETCC: the i16 boolean is
|
|
; widened with a zero high half (this used to be "Cannot select").
|
|
define i32 @set32_ult(i32 %a, i32 %b) {
|
|
; CHECK-LABEL: set32_ult:
|
|
; CHECK: cmp 0x8, s
|
|
; CHECK-NEXT: lda 0xd0
|
|
; CHECK-NEXT: sbc 0xa, s
|
|
; CHECK-NEXT: bcc
|
|
; CHECK: ldx #0x0
|
|
; CHECK: rtl
|
|
%c = icmp ult i32 %a, %b
|
|
%z = zext i1 %c to i32
|
|
ret i32 %z
|
|
}
|
|
|
|
define i16 @sel16_slt(i32 %a, i32 %b, i16 %x, i16 %y) {
|
|
; CHECK-LABEL: sel16_slt:
|
|
; CHECK-NOT: php
|
|
; CHECK: cmp 0xc, s
|
|
; CHECK-NEXT: lda
|
|
; CHECK-NEXT: sbc
|
|
; CHECK-NEXT: bcc
|
|
; CHECK: rtl
|
|
%c = icmp slt i32 %a, %b
|
|
%r = select i1 %c, i16 %x, i16 %y
|
|
ret i16 %r
|
|
}
|
|
|
|
define i32 @sel32_uge(i32 %a, i32 %b, i32 %x, i32 %y) {
|
|
; CHECK-LABEL: sel32_uge:
|
|
; CHECK: cmp 0xa, s
|
|
; CHECK-NEXT: lda 0xd0
|
|
; CHECK-NEXT: sbc 0xc, s
|
|
; CHECK-NEXT: bcs
|
|
; CHECK: rtl
|
|
%c = icmp uge i32 %a, %b
|
|
%r = select i1 %c, i32 %x, i32 %y
|
|
ret i32 %r
|
|
}
|
|
|
|
; The loop shape from JoeyLib's old sfxCopyUnsigned: the latch's i < n is
|
|
; the chain and one bcc back to the top, and every i32 += 1 keeps the
|
|
; carry into its high half (the bne skips over it).
|
|
define void @loop_ult(ptr %dst, i32 %n) {
|
|
; CHECK-LABEL: loop_ult:
|
|
; CHECK: [[TOP:.LBB[0-9_]+]]: ; %body
|
|
; CHECK-NOT: php
|
|
; CHECK: inc 0xd2
|
|
; CHECK-NEXT: bne
|
|
; CHECK-NEXT: lda 0x3, s
|
|
; CHECK-NEXT: inc a
|
|
; CHECK-NEXT: sta 0x3, s
|
|
; CHECK: inc 0xd4
|
|
; CHECK-NEXT: bne
|
|
; CHECK-NEXT: lda 0x5, s
|
|
; CHECK-NEXT: inc a
|
|
; CHECK-NEXT: sta 0x5, s
|
|
; CHECK: lda 0xd4
|
|
; CHECK-NEXT: cmp 0xc, s
|
|
; CHECK-NEXT: lda 0x5, s
|
|
; CHECK-NEXT: sbc 0xe, s
|
|
; CHECK-NEXT: bcc [[TOP]]
|
|
; CHECK: rtl
|
|
entry:
|
|
%z = icmp eq i32 %n, 0
|
|
br i1 %z, label %done, label %body
|
|
body:
|
|
%i = phi i32 [ 0, %entry ], [ %inc, %body ]
|
|
%p = getelementptr inbounds i8, ptr %dst, i32 %i
|
|
store i8 1, ptr %p
|
|
%inc = add nuw i32 %i, 1
|
|
%c = icmp ult i32 %inc, %n
|
|
br i1 %c, label %body, label %done
|
|
done:
|
|
ret void
|
|
}
|