; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=avr -mattr=+movw -mattr=+elpm -mattr=+elpmx -mattr=+lpm -mattr=+lpmx -verify-machineinstrs \
; RUN: | FileCheck %s
; RUN: llc < %s -mtriple=avr -mattr=+movw -mattr=+elpm -mattr=-elpmx -mattr=+lpm -mattr=-lpmx -verify-machineinstrs \
; RUN: | FileCheck --check-prefix=NOX %s
@arr0 = addrspace(1) constant [4 x i16] [i16 123, i16 24, i16 56, i16 37], align 1
@arr1 = addrspace(2) constant [4 x i16] [i16 123, i16 34, i16 46, i16 27], align 1
@arr2 = addrspace(3) constant [4 x i16] [i16 123, i16 23, i16 45, i16 17], align 1
define i16 @foo0(i16 %a, i16 %b) {
; CHECK-LABEL: foo0:
; CHECK: ; %bb.0: ; %entry
; CHECK-NEXT: lsl r22
; CHECK-NEXT: rol r23
; CHECK-NEXT: subi r22, lo8(-(arr0))
; CHECK-NEXT: sbci r23, hi8(-(arr0))
; CHECK-NEXT: movw r30, r22
; CHECK-NEXT: lpm r18, Z+
; CHECK-NEXT: lpm r19, Z
; CHECK-NEXT: lsl r24
; CHECK-NEXT: rol r25
; CHECK-NEXT: subi r24, lo8(-(arr0))
; CHECK-NEXT: sbci r25, hi8(-(arr0))
; CHECK-NEXT: movw r30, r24
; CHECK-NEXT: lpm r24, Z+
; CHECK-NEXT: lpm r25, Z
; CHECK-NEXT: sub r24, r18
; CHECK-NEXT: sbc r25, r19
; CHECK-NEXT: ret
;
; NOX-LABEL: foo0:
; NOX: ; %bb.0: ; %entry
; NOX-NEXT: lsl r22
; NOX-NEXT: rol r23
; NOX-NEXT: subi r22, lo8(-(arr0))
; NOX-NEXT: sbci r23, hi8(-(arr0))
; NOX-NEXT: movw r30, r22
; NOX-NEXT: lpm
; NOX-NEXT: mov r18, r0
; NOX-NEXT: adiw r30, 1
; NOX-NEXT: lpm
; NOX-NEXT: mov r19, r0
; NOX-NEXT: lsl r24
; NOX-NEXT: rol r25
; NOX-NEXT: subi r24, lo8(-(arr0))
; NOX-NEXT: sbci r25, hi8(-(arr0))
; NOX-NEXT: movw r30, r24
; NOX-NEXT: lpm
; NOX-NEXT: mov r24, r0
; NOX-NEXT: adiw r30, 1
; NOX-NEXT: lpm
; NOX-NEXT: mov r25, r0
; NOX-NEXT: sub r24, r18
; NOX-NEXT: sbc r25, r19
; NOX-NEXT: ret
entry:
%arrayidx = getelementptr inbounds [4 x i16], ptr addrspace(1) @arr0, i16 0, i16 %a
%0 = load i16, ptr addrspace(1) %arrayidx, align 1
%arrayidx1 = getelementptr inbounds [4 x i16], ptr addrspace(1) @arr0, i16 0, i16 %b
%1 = load i16, ptr addrspace(1) %arrayidx1, align 1
%sub = sub nsw i16 %0, %1
ret i16 %sub
}
define i16 @foo1(i16 %a, i16 %b) {
; CHECK-LABEL: foo1:
; CHECK: ; %bb.0: ; %entry
; CHECK-NEXT: lsl r22
; CHECK-NEXT: rol r23
; CHECK-NEXT: subi r22, lo8(-(arr1))
; CHECK-NEXT: sbci r23, hi8(-(arr1))
; CHECK-NEXT: movw r30, r22
; CHECK-NEXT: ldi r18, 1
; CHECK-NEXT: out 59, r18
; CHECK-NEXT: elpm r20, Z+
; CHECK-NEXT: elpm r21, Z
; CHECK-NEXT: lsl r24
; CHECK-NEXT: rol r25
; CHECK-NEXT: subi r24, lo8(-(arr0))
; CHECK-NEXT: sbci r25, hi8(-(arr0))
; CHECK-NEXT: movw r30, r24
; CHECK-NEXT: lpm r24, Z+
; CHECK-NEXT: lpm r25, Z
; CHECK-NEXT: sub r24, r20
; CHECK-NEXT: sbc r25, r21
; CHECK-NEXT: ret
;
; NOX-LABEL: foo1:
; NOX: ; %bb.0: ; %entry
; NOX-NEXT: lsl r22
; NOX-NEXT: rol r23
; NOX-NEXT: subi r22, lo8(-(arr1))
; NOX-NEXT: sbci r23, hi8(-(arr1))
; NOX-NEXT: movw r30, r22
; NOX-NEXT: ldi r18, 1
; NOX-NEXT: out 59, r18
; NOX-NEXT: elpm
; NOX-NEXT: mov r20, r0
; NOX-NEXT: adiw r30, 1
; NOX-NEXT: elpm
; NOX-NEXT: mov r21, r0
; NOX-NEXT: lsl r24
; NOX-NEXT: rol r25
; NOX-NEXT: subi r24, lo8(-(arr0))
; NOX-NEXT: sbci r25, hi8(-(arr0))
; NOX-NEXT: movw r30, r24
; NOX-NEXT: lpm
; NOX-NEXT: mov r24, r0
; NOX-NEXT: adiw r30, 1
; NOX-NEXT: lpm
; NOX-NEXT: mov r25, r0
; NOX-NEXT: sub r24, r20
; NOX-NEXT: sbc r25, r21
; NOX-NEXT: ret
entry:
%arrayidx = getelementptr inbounds [4 x i16], ptr addrspace(1) @arr0, i16 0, i16 %a
%0 = load i16, ptr addrspace(1) %arrayidx, align 1
%arrayidx1 = getelementptr inbounds [4 x i16], ptr addrspace(2) @arr1, i16 0, i16 %b
%1 = load i16, ptr addrspace(2) %arrayidx1, align 1
%sub = sub nsw i16 %0, %1
ret i16 %sub
}
define i16 @foo2(i16 %a, i16 %b) {
; CHECK-LABEL: foo2:
; CHECK: ; %bb.0: ; %entry
; CHECK-NEXT: lsl r24
; CHECK-NEXT: rol r25
; CHECK-NEXT: subi r24, lo8(-(arr2))
; CHECK-NEXT: sbci r25, hi8(-(arr2))
; CHECK-NEXT: movw r30, r24
; CHECK-NEXT: ldi r18, 2
; CHECK-NEXT: out 59, r18
; CHECK-NEXT: elpm r24, Z+
; CHECK-NEXT: elpm r25, Z
; CHECK-NEXT: lsl r22
; CHECK-NEXT: rol r23
; CHECK-NEXT: subi r22, lo8(-(arr0))
; CHECK-NEXT: sbci r23, hi8(-(arr0))
; CHECK-NEXT: movw r30, r22
; CHECK-NEXT: lpm r18, Z+
; CHECK-NEXT: lpm r19, Z
; CHECK-NEXT: sub r24, r18
; CHECK-NEXT: sbc r25, r19
; CHECK-NEXT: ret
;
; NOX-LABEL: foo2:
; NOX: ; %bb.0: ; %entry
; NOX-NEXT: lsl r24
; NOX-NEXT: rol r25
; NOX-NEXT: subi r24, lo8(-(arr2))
; NOX-NEXT: sbci r25, hi8(-(arr2))
; NOX-NEXT: movw r30, r24
; NOX-NEXT: ldi r18, 2
; NOX-NEXT: out 59, r18
; NOX-NEXT: elpm
; NOX-NEXT: mov r24, r0
; NOX-NEXT: adiw r30, 1
; NOX-NEXT: elpm
; NOX-NEXT: mov r25, r0
; NOX-NEXT: lsl r22
; NOX-NEXT: rol r23
; NOX-NEXT: subi r22, lo8(-(arr0))
; NOX-NEXT: sbci r23, hi8(-(arr0))
; NOX-NEXT: movw r30, r22
; NOX-NEXT: lpm
; NOX-NEXT: mov r18, r0
; NOX-NEXT: adiw r30, 1
; NOX-NEXT: lpm
; NOX-NEXT: mov r19, r0
; NOX-NEXT: sub r24, r18
; NOX-NEXT: sbc r25, r19
; NOX-NEXT: ret
entry:
%arrayidx = getelementptr inbounds [4 x i16], ptr addrspace(3) @arr2, i16 0, i16 %a
%0 = load i16, ptr addrspace(3) %arrayidx, align 1
%arrayidx1 = getelementptr inbounds [4 x i16], ptr addrspace(1) @arr0, i16 0, i16 %b
%1 = load i16, ptr addrspace(1) %arrayidx1, align 1
%sub = sub nsw i16 %0, %1
ret i16 %sub
}
define i16 @foo3(i16 %a, i16 %b) {
; CHECK-LABEL: foo3:
; CHECK: ; %bb.0: ; %entry
; CHECK-NEXT: lsl r22
; CHECK-NEXT: rol r23
; CHECK-NEXT: subi r22, lo8(-(arr1))
; CHECK-NEXT: sbci r23, hi8(-(arr1))
; CHECK-NEXT: movw r30, r22
; CHECK-NEXT: ldi r18, 1
; CHECK-NEXT: out 59, r18
; CHECK-NEXT: elpm r20, Z+
; CHECK-NEXT: elpm r21, Z
; CHECK-NEXT: lsl r24
; CHECK-NEXT: rol r25
; CHECK-NEXT: subi r24, lo8(-(arr2))
; CHECK-NEXT: sbci r25, hi8(-(arr2))
; CHECK-NEXT: movw r30, r24
; CHECK-NEXT: ldi r18, 2
; CHECK-NEXT: out 59, r18
; CHECK-NEXT: elpm r24, Z+
; CHECK-NEXT: elpm r25, Z
; CHECK-NEXT: sub r24, r20
; CHECK-NEXT: sbc r25, r21
; CHECK-NEXT: ret
;
; NOX-LABEL: foo3:
; NOX: ; %bb.0: ; %entry
; NOX-NEXT: lsl r22
; NOX-NEXT: rol r23
; NOX-NEXT: subi r22, lo8(-(arr1))
; NOX-NEXT: sbci r23, hi8(-(arr1))
; NOX-NEXT: movw r30, r22
; NOX-NEXT: ldi r18, 1
; NOX-NEXT: out 59, r18
; NOX-NEXT: elpm
; NOX-NEXT: mov r20, r0
; NOX-NEXT: adiw r30, 1
; NOX-NEXT: elpm
; NOX-NEXT: mov r21, r0
; NOX-NEXT: lsl r24
; NOX-NEXT: rol r25
; NOX-NEXT: subi r24, lo8(-(arr2))
; NOX-NEXT: sbci r25, hi8(-(arr2))
; NOX-NEXT: movw r30, r24
; NOX-NEXT: ldi r18, 2
; NOX-NEXT: out 59, r18
; NOX-NEXT: elpm
; NOX-NEXT: mov r24, r0
; NOX-NEXT: adiw r30, 1
; NOX-NEXT: elpm
; NOX-NEXT: mov r25, r0
; NOX-NEXT: sub r24, r20
; NOX-NEXT: sbc r25, r21
; NOX-NEXT: ret
entry:
%arrayidx = getelementptr inbounds [4 x i16], ptr addrspace(3) @arr2, i16 0, i16 %a
%0 = load i16, ptr addrspace(3) %arrayidx, align 1
%arrayidx1 = getelementptr inbounds [4 x i16], ptr addrspace(2) @arr1, i16 0, i16 %b
%1 = load i16, ptr addrspace(2) %arrayidx1, align 1
%sub = sub nsw i16 %0, %1
ret i16 %sub
}
@arrb1 = addrspace(1) constant [4 x i8] c"abcd", align 1
@arrb3 = addrspace(3) constant [4 x i8] c"1234", align 1
@arrb5 = addrspace(5) constant [4 x i8] c"HJLQ", align 1
define signext i8 @foob0(i16 %a, i16 %b) {
; CHECK-LABEL: foob0:
; CHECK: ; %bb.0: ; %entry
; CHECK-NEXT: subi r22, lo8(-(arrb1))
; CHECK-NEXT: sbci r23, hi8(-(arrb1))
; CHECK-NEXT: movw r30, r22
; CHECK-NEXT: lpm r18, Z
; CHECK-NEXT: subi r24, lo8(-(arrb1))
; CHECK-NEXT: sbci r25, hi8(-(arrb1))
; CHECK-NEXT: movw r30, r24
; CHECK-NEXT: lpm r24, Z
; CHECK-NEXT: sub r24, r18
; CHECK-NEXT: mov r25, r24
; CHECK-NEXT: lsl r25
; CHECK-NEXT: sbc r25, r25
; CHECK-NEXT: ret
;
; NOX-LABEL: foob0:
; NOX: ; %bb.0: ; %entry
; NOX-NEXT: subi r22, lo8(-(arrb1))
; NOX-NEXT: sbci r23, hi8(-(arrb1))
; NOX-NEXT: movw r30, r22
; NOX-NEXT: lpm
; NOX-NEXT: mov r18, r0
; NOX-NEXT: subi r24, lo8(-(arrb1))
; NOX-NEXT: sbci r25, hi8(-(arrb1))
; NOX-NEXT: movw r30, r24
; NOX-NEXT: lpm
; NOX-NEXT: mov r24, r0
; NOX-NEXT: sub r24, r18
; NOX-NEXT: mov r25, r24
; NOX-NEXT: lsl r25
; NOX-NEXT: sbc r25, r25
; NOX-NEXT: ret
entry:
%arrayidx = getelementptr inbounds [4 x i8], ptr addrspace(1) @arrb1, i16 0, i16 %a
%0 = load i8, ptr addrspace(1) %arrayidx, align 1
%arrayidx1 = getelementptr inbounds [4 x i8], ptr addrspace(1) @arrb1, i16 0, i16 %b
%1 = load i8, ptr addrspace(1) %arrayidx1, align 1
%sub = sub i8 %0, %1
ret i8 %sub
}
define signext i8 @foob1(i16 %a, i16 %b) {
; CHECK-LABEL: foob1:
; CHECK: ; %bb.0: ; %entry
; CHECK-NEXT: subi r22, lo8(-(arrb3))
; CHECK-NEXT: sbci r23, hi8(-(arrb3))
; CHECK-NEXT: movw r30, r22
; CHECK-NEXT: ldi r18, 2
; CHECK-NEXT: out 59, r18
; CHECK-NEXT: elpm r18, Z
; CHECK-NEXT: subi r24, lo8(-(arrb1))
; CHECK-NEXT: sbci r25, hi8(-(arrb1))
; CHECK-NEXT: movw r30, r24
; CHECK-NEXT: lpm r24, Z
; CHECK-NEXT: sub r24, r18
; CHECK-NEXT: mov r25, r24
; CHECK-NEXT: lsl r25
; CHECK-NEXT: sbc r25, r25
; CHECK-NEXT: ret
;
; NOX-LABEL: foob1:
; NOX: ; %bb.0: ; %entry
; NOX-NEXT: subi r22, lo8(-(arrb3))
; NOX-NEXT: sbci r23, hi8(-(arrb3))
; NOX-NEXT: movw r30, r22
; NOX-NEXT: ldi r18, 2
; NOX-NEXT: out 59, r18
; NOX-NEXT: elpm
; NOX-NEXT: mov r18, r0
; NOX-NEXT: subi r24, lo8(-(arrb1))
; NOX-NEXT: sbci r25, hi8(-(arrb1))
; NOX-NEXT: movw r30, r24
; NOX-NEXT: lpm
; NOX-NEXT: mov r24, r0
; NOX-NEXT: sub r24, r18
; NOX-NEXT: mov r25, r24
; NOX-NEXT: lsl r25
; NOX-NEXT: sbc r25, r25
; NOX-NEXT: ret
entry:
%arrayidx = getelementptr inbounds [4 x i8], ptr addrspace(1) @arrb1, i16 0, i16 %a
%0 = load i8, ptr addrspace(1) %arrayidx, align 1
%arrayidx1 = getelementptr inbounds [4 x i8], ptr addrspace(3) @arrb3, i16 0, i16 %b
%1 = load i8, ptr addrspace(3) %arrayidx1, align 1
%sub = sub i8 %0, %1
ret i8 %sub
}
define signext i8 @foob2(i16 %a, i16 %b) {
; CHECK-LABEL: foob2:
; CHECK: ; %bb.0: ; %entry
; CHECK-NEXT: subi r24, lo8(-(arrb5))
; CHECK-NEXT: sbci r25, hi8(-(arrb5))
; CHECK-NEXT: movw r30, r24
; CHECK-NEXT: ldi r24, 4
; CHECK-NEXT: out 59, r24
; CHECK-NEXT: elpm r24, Z
; CHECK-NEXT: subi r22, lo8(-(arrb1))
; CHECK-NEXT: sbci r23, hi8(-(arrb1))
; CHECK-NEXT: movw r30, r22
; CHECK-NEXT: lpm r25, Z
; CHECK-NEXT: sub r24, r25
; CHECK-NEXT: mov r25, r24
; CHECK-NEXT: lsl r25
; CHECK-NEXT: sbc r25, r25
; CHECK-NEXT: ret
;
; NOX-LABEL: foob2:
; NOX: ; %bb.0: ; %entry
; NOX-NEXT: subi r24, lo8(-(arrb5))
; NOX-NEXT: sbci r25, hi8(-(arrb5))
; NOX-NEXT: movw r30, r24
; NOX-NEXT: ldi r24, 4
; NOX-NEXT: out 59, r24
; NOX-NEXT: elpm
; NOX-NEXT: mov r24, r0
; NOX-NEXT: subi r22, lo8(-(arrb1))
; NOX-NEXT: sbci r23, hi8(-(arrb1))
; NOX-NEXT: movw r30, r22
; NOX-NEXT: lpm
; NOX-NEXT: mov r25, r0
; NOX-NEXT: sub r24, r25
; NOX-NEXT: mov r25, r24
; NOX-NEXT: lsl r25
; NOX-NEXT: sbc r25, r25
; NOX-NEXT: ret
entry:
%arrayidx = getelementptr inbounds [4 x i8], ptr addrspace(5) @arrb5, i16 0, i16 %a
%0 = load i8, ptr addrspace(5) %arrayidx, align 1
%arrayidx1 = getelementptr inbounds [4 x i8], ptr addrspace(1) @arrb1, i16 0, i16 %b
%1 = load i8, ptr addrspace(1) %arrayidx1, align 1
%sub = sub i8 %0, %1
ret i8 %sub
}
define signext i8 @foob3(i16 %a, i16 %b) {
; CHECK-LABEL: foob3:
; CHECK: ; %bb.0: ; %entry
; CHECK-NEXT: subi r22, lo8(-(arrb5))
; CHECK-NEXT: sbci r23, hi8(-(arrb5))
; CHECK-NEXT: movw r30, r22
; CHECK-NEXT: ldi r18, 4
; CHECK-NEXT: out 59, r18
; CHECK-NEXT: elpm r18, Z
; CHECK-NEXT: subi r24, lo8(-(arrb3))
; CHECK-NEXT: sbci r25, hi8(-(arrb3))
; CHECK-NEXT: movw r30, r24
; CHECK-NEXT: ldi r24, 2
; CHECK-NEXT: out 59, r24
; CHECK-NEXT: elpm r24, Z
; CHECK-NEXT: sub r24, r18
; CHECK-NEXT: mov r25, r24
; CHECK-NEXT: lsl r25
; CHECK-NEXT: sbc r25, r25
; CHECK-NEXT: ret
;
; NOX-LABEL: foob3:
; NOX: ; %bb.0: ; %entry
; NOX-NEXT: subi r22, lo8(-(arrb5))
; NOX-NEXT: sbci r23, hi8(-(arrb5))
; NOX-NEXT: movw r30, r22
; NOX-NEXT: ldi r18, 4
; NOX-NEXT: out 59, r18
; NOX-NEXT: elpm
; NOX-NEXT: mov r18, r0
; NOX-NEXT: subi r24, lo8(-(arrb3))
; NOX-NEXT: sbci r25, hi8(-(arrb3))
; NOX-NEXT: movw r30, r24
; NOX-NEXT: ldi r24, 2
; NOX-NEXT: out 59, r24
; NOX-NEXT: elpm
; NOX-NEXT: mov r24, r0
; NOX-NEXT: sub r24, r18
; NOX-NEXT: mov r25, r24
; NOX-NEXT: lsl r25
; NOX-NEXT: sbc r25, r25
; NOX-NEXT: ret
entry:
%arrayidx = getelementptr inbounds [4 x i8], ptr addrspace(3) @arrb3, i16 0, i16 %a
%0 = load i8, ptr addrspace(3) %arrayidx, align 1
%arrayidx1 = getelementptr inbounds [4 x i8], ptr addrspace(5) @arrb5, i16 0, i16 %b
%1 = load i8, ptr addrspace(5) %arrayidx1, align 1
%sub = sub i8 %0, %1
ret i8 %sub
}
define signext i8 @foob4(i16 %a, i16 %b) {
; CHECK-LABEL: foob4:
; CHECK: ; %bb.0: ; %entry
; CHECK-NEXT: subi r22, lo8(-(arrb3))
; CHECK-NEXT: sbci r23, hi8(-(arrb3))
; CHECK-NEXT: movw r30, r22
; CHECK-NEXT: ldi r18, 2
; CHECK-NEXT: out 59, r18
; CHECK-NEXT: elpm r19, Z
; CHECK-NEXT: subi r24, lo8(-(arrb3))
; CHECK-NEXT: sbci r25, hi8(-(arrb3))
; CHECK-NEXT: movw r30, r24
; CHECK-NEXT: out 59, r18
; CHECK-NEXT: elpm r24, Z
; CHECK-NEXT: sub r24, r19
; CHECK-NEXT: mov r25, r24
; CHECK-NEXT: lsl r25
; CHECK-NEXT: sbc r25, r25
; CHECK-NEXT: ret
;
; NOX-LABEL: foob4:
; NOX: ; %bb.0: ; %entry
; NOX-NEXT: subi r22, lo8(-(arrb3))
; NOX-NEXT: sbci r23, hi8(-(arrb3))
; NOX-NEXT: movw r30, r22
; NOX-NEXT: ldi r18, 2
; NOX-NEXT: out 59, r18
; NOX-NEXT: elpm
; NOX-NEXT: mov r19, r0
; NOX-NEXT: subi r24, lo8(-(arrb3))
; NOX-NEXT: sbci r25, hi8(-(arrb3))
; NOX-NEXT: movw r30, r24
; NOX-NEXT: out 59, r18
; NOX-NEXT: elpm
; NOX-NEXT: mov r24, r0
; NOX-NEXT: sub r24, r19
; NOX-NEXT: mov r25, r24
; NOX-NEXT: lsl r25
; NOX-NEXT: sbc r25, r25
; NOX-NEXT: ret
entry:
%arrayidx = getelementptr inbounds [4 x i8], ptr addrspace(3) @arrb3, i16 0, i16 %a
%0 = load i8, ptr addrspace(3) %arrayidx, align 1
%arrayidx1 = getelementptr inbounds [4 x i8], ptr addrspace(3) @arrb3, i16 0, i16 %b
%1 = load i8, ptr addrspace(3) %arrayidx1, align 1
%sub = sub i8 %0, %1
ret i8 %sub
}