; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=aarch64 -o - | FileCheck %s
; RUN: llc < %s -mtriple=aarch64_be -o - | FileCheck %s --check-prefix=CHECKBE
define i64 @load32_and16_and(ptr %p, i64 %y) {
; CHECK-LABEL: load32_and16_and:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr w8, [x0]
; CHECK-NEXT: and w8, w1, w8
; CHECK-NEXT: and x0, x8, #0xffff
; CHECK-NEXT: ret
;
; CHECKBE-LABEL: load32_and16_and:
; CHECKBE: // %bb.0:
; CHECKBE-NEXT: ldr w8, [x0]
; CHECKBE-NEXT: and w8, w1, w8
; CHECKBE-NEXT: and x0, x8, #0xffff
; CHECKBE-NEXT: ret
%x = load i32, ptr %p, align 4
%xz = zext i32 %x to i64
%ym = and i64 %y, 65535
%r = and i64 %ym, %xz
ret i64 %r
}
define i64 @load32_and16_andr(ptr %p, i64 %y) {
; CHECK-LABEL: load32_and16_andr:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr w8, [x0]
; CHECK-NEXT: and w8, w1, w8
; CHECK-NEXT: and x0, x8, #0xffff
; CHECK-NEXT: ret
;
; CHECKBE-LABEL: load32_and16_andr:
; CHECKBE: // %bb.0:
; CHECKBE-NEXT: ldr w8, [x0]
; CHECKBE-NEXT: and w8, w1, w8
; CHECKBE-NEXT: and x0, x8, #0xffff
; CHECKBE-NEXT: ret
%x = load i32, ptr %p, align 4
%xz = zext i32 %x to i64
%a = and i64 %y, %xz
%r = and i64 %a, 65535
ret i64 %r
}
define i64 @load32_and16_and_sext(ptr %p, i64 %y) {
; CHECK-LABEL: load32_and16_and_sext:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr w8, [x0]
; CHECK-NEXT: and w8, w1, w8
; CHECK-NEXT: and x0, x8, #0xffff
; CHECK-NEXT: ret
;
; CHECKBE-LABEL: load32_and16_and_sext:
; CHECKBE: // %bb.0:
; CHECKBE-NEXT: ldr w8, [x0]
; CHECKBE-NEXT: and w8, w1, w8
; CHECKBE-NEXT: and x0, x8, #0xffff
; CHECKBE-NEXT: ret
%x = load i32, ptr %p, align 4
%xz = sext i32 %x to i64
%a = and i64 %y, %xz
%r = and i64 %a, 65535
ret i64 %r
}
define i64 @load32_and16_or(ptr %p, i64 %y) {
; CHECK-LABEL: load32_and16_or:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr w8, [x0]
; CHECK-NEXT: orr w8, w1, w8
; CHECK-NEXT: and x0, x8, #0xffff
; CHECK-NEXT: ret
;
; CHECKBE-LABEL: load32_and16_or:
; CHECKBE: // %bb.0:
; CHECKBE-NEXT: ldr w8, [x0]
; CHECKBE-NEXT: orr w8, w1, w8
; CHECKBE-NEXT: and x0, x8, #0xffff
; CHECKBE-NEXT: ret
%x = load i32, ptr %p, align 4
%xz = zext i32 %x to i64
%a = or i64 %y, %xz
%r = and i64 %a, 65535
ret i64 %r
}
define i64 @load32_and16_orr(ptr %p, i64 %y) {
; CHECK-LABEL: load32_and16_orr:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr w8, [x0]
; CHECK-NEXT: and x9, x1, #0xffff
; CHECK-NEXT: orr x0, x9, x8
; CHECK-NEXT: ret
;
; CHECKBE-LABEL: load32_and16_orr:
; CHECKBE: // %bb.0:
; CHECKBE-NEXT: ldr w8, [x0]
; CHECKBE-NEXT: and x9, x1, #0xffff
; CHECKBE-NEXT: orr x0, x9, x8
; CHECKBE-NEXT: ret
%x = load i32, ptr %p, align 4
%xz = zext i32 %x to i64
%ym = and i64 %y, 65535
%r = or i64 %ym, %xz
ret i64 %r
}
define i64 @load32_and16_xorm1(ptr %p) {
; CHECK-LABEL: load32_and16_xorm1:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr w8, [x0]
; CHECK-NEXT: mvn w8, w8
; CHECK-NEXT: and x0, x8, #0xffff
; CHECK-NEXT: ret
;
; CHECKBE-LABEL: load32_and16_xorm1:
; CHECKBE: // %bb.0:
; CHECKBE-NEXT: ldr w8, [x0]
; CHECKBE-NEXT: mvn w8, w8
; CHECKBE-NEXT: and x0, x8, #0xffff
; CHECKBE-NEXT: ret
%x = load i32, ptr %p, align 4
%xz = zext i32 %x to i64
%a = xor i64 %xz, -1
%r = and i64 %a, 65535
ret i64 %r
}
define i64 @load64_and16(ptr %p, i128 %y) {
; CHECK-LABEL: load64_and16:
; CHECK: // %bb.0:
; CHECK-NEXT: ldrh w8, [x0]
; CHECK-NEXT: and x0, x2, x8
; CHECK-NEXT: ret
;
; CHECKBE-LABEL: load64_and16:
; CHECKBE: // %bb.0:
; CHECKBE-NEXT: ldrh w8, [x0, #6]
; CHECKBE-NEXT: and x0, x3, x8
; CHECKBE-NEXT: ret
%x = load i64, ptr %p, align 4
%xz = zext i64 %x to i128
%a = and i128 %y, %xz
%t = trunc i128 %a to i64
%r = and i64 %t, 65535
ret i64 %r
}
define i64 @load16_and16(ptr %p, i64 %y) {
; CHECK-LABEL: load16_and16:
; CHECK: // %bb.0:
; CHECK-NEXT: ldrh w8, [x0]
; CHECK-NEXT: and x0, x1, x8
; CHECK-NEXT: ret
;
; CHECKBE-LABEL: load16_and16:
; CHECKBE: // %bb.0:
; CHECKBE-NEXT: ldrh w8, [x0]
; CHECKBE-NEXT: and x0, x1, x8
; CHECKBE-NEXT: ret
%x = load i16, ptr %p, align 4
%xz = zext i16 %x to i64
%a = and i64 %y, %xz
%r = and i64 %a, 65535
ret i64 %r
}
define i64 @load16_and8(ptr %p, i64 %y) {
; CHECK-LABEL: load16_and8:
; CHECK: // %bb.0:
; CHECK-NEXT: ldrh w8, [x0]
; CHECK-NEXT: and w8, w1, w8
; CHECK-NEXT: and x0, x8, #0xff
; CHECK-NEXT: ret
;
; CHECKBE-LABEL: load16_and8:
; CHECKBE: // %bb.0:
; CHECKBE-NEXT: ldrh w8, [x0]
; CHECKBE-NEXT: and w8, w1, w8
; CHECKBE-NEXT: and x0, x8, #0xff
; CHECKBE-NEXT: ret
%x = load i16, ptr %p, align 4
%xz = zext i16 %x to i64
%a = and i64 %y, %xz
%r = and i64 %a, 255
ret i64 %r
}
define i64 @load16_and7(ptr %p, i64 %y) {
; CHECK-LABEL: load16_and7:
; CHECK: // %bb.0:
; CHECK-NEXT: ldrh w8, [x0]
; CHECK-NEXT: and w8, w1, w8
; CHECK-NEXT: and x0, x8, #0x7f
; CHECK-NEXT: ret
;
; CHECKBE-LABEL: load16_and7:
; CHECKBE: // %bb.0:
; CHECKBE-NEXT: ldrh w8, [x0]
; CHECKBE-NEXT: and w8, w1, w8
; CHECKBE-NEXT: and x0, x8, #0x7f
; CHECKBE-NEXT: ret
%x = load i16, ptr %p, align 4
%xz = zext i16 %x to i64
%a = and i64 %y, %xz
%r = and i64 %a, 127
ret i64 %r
}
define i64 @load8_and16(ptr %p, i64 %y) {
; CHECK-LABEL: load8_and16:
; CHECK: // %bb.0:
; CHECK-NEXT: ldrb w8, [x0]
; CHECK-NEXT: and x0, x1, x8
; CHECK-NEXT: ret
;
; CHECKBE-LABEL: load8_and16:
; CHECKBE: // %bb.0:
; CHECKBE-NEXT: ldrb w8, [x0]
; CHECKBE-NEXT: and x0, x1, x8
; CHECKBE-NEXT: ret
%x = load i8, ptr %p, align 4
%xz = zext i8 %x to i64
%a = and i64 %y, %xz
%r = and i64 %a, 65535
ret i64 %r
}
define i64 @load8_and16_zext(ptr %p, i8 %y) {
; CHECK-LABEL: load8_and16_zext:
; CHECK: // %bb.0:
; CHECK-NEXT: ldrb w8, [x0]
; CHECK-NEXT: and w8, w1, w8
; CHECK-NEXT: and x0, x8, #0xff
; CHECK-NEXT: ret
;
; CHECKBE-LABEL: load8_and16_zext:
; CHECKBE: // %bb.0:
; CHECKBE-NEXT: ldrb w8, [x0]
; CHECKBE-NEXT: and w8, w1, w8
; CHECKBE-NEXT: and x0, x8, #0xff
; CHECKBE-NEXT: ret
%x = load i8, ptr %p, align 4
%xz = zext i8 %x to i64
%yz = zext i8 %y to i64
%a = and i64 %yz, %xz
%r = and i64 %a, 65535
ret i64 %r
}
define i64 @load8_and16_sext(ptr %p, i8 %y) {
; CHECK-LABEL: load8_and16_sext:
; CHECK: // %bb.0:
; CHECK-NEXT: ldrb w8, [x0]
; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
; CHECK-NEXT: and x0, x1, x8
; CHECK-NEXT: ret
;
; CHECKBE-LABEL: load8_and16_sext:
; CHECKBE: // %bb.0:
; CHECKBE-NEXT: ldrb w8, [x0]
; CHECKBE-NEXT: // kill: def $w1 killed $w1 def $x1
; CHECKBE-NEXT: and x0, x1, x8
; CHECKBE-NEXT: ret
%x = load i8, ptr %p, align 4
%xz = zext i8 %x to i64
%yz = sext i8 %y to i64
%a = and i64 %yz, %xz
%r = and i64 %a, 65535
ret i64 %r
}
define i64 @load8_and16_or(ptr %p, i64 %y) {
; CHECK-LABEL: load8_and16_or:
; CHECK: // %bb.0:
; CHECK-NEXT: ldrb w8, [x0]
; CHECK-NEXT: orr w8, w1, w8
; CHECK-NEXT: and x0, x8, #0xffff
; CHECK-NEXT: ret
;
; CHECKBE-LABEL: load8_and16_or:
; CHECKBE: // %bb.0:
; CHECKBE-NEXT: ldrb w8, [x0]
; CHECKBE-NEXT: orr w8, w1, w8
; CHECKBE-NEXT: and x0, x8, #0xffff
; CHECKBE-NEXT: ret
%x = load i8, ptr %p, align 4
%xz = zext i8 %x to i64
%a = or i64 %y, %xz
%r = and i64 %a, 65535
ret i64 %r
}
define i64 @load16_and8_manyext(ptr %p, i32 %y) {
; CHECK-LABEL: load16_and8_manyext:
; CHECK: // %bb.0:
; CHECK-NEXT: ldrh w8, [x0]
; CHECK-NEXT: and w8, w1, w8
; CHECK-NEXT: and x0, x8, #0xff
; CHECK-NEXT: ret
;
; CHECKBE-LABEL: load16_and8_manyext:
; CHECKBE: // %bb.0:
; CHECKBE-NEXT: ldrh w8, [x0]
; CHECKBE-NEXT: and w8, w1, w8
; CHECKBE-NEXT: and x0, x8, #0xff
; CHECKBE-NEXT: ret
%x = load i16, ptr %p, align 4
%xz = zext i16 %x to i32
%a = and i32 %y, %xz
%az = zext i32 %a to i64
%r = and i64 %az, 255
ret i64 %r
}
define i64 @multiple_load(ptr %p, ptr %q) {
; CHECK-LABEL: multiple_load:
; CHECK: // %bb.0:
; CHECK-NEXT: ldrh w8, [x0]
; CHECK-NEXT: ldr w9, [x1]
; CHECK-NEXT: and w8, w9, w8
; CHECK-NEXT: and x0, x8, #0xff
; CHECK-NEXT: ret
;
; CHECKBE-LABEL: multiple_load:
; CHECKBE: // %bb.0:
; CHECKBE-NEXT: ldrh w8, [x0]
; CHECKBE-NEXT: ldr w9, [x1]
; CHECKBE-NEXT: and w8, w9, w8
; CHECKBE-NEXT: and x0, x8, #0xff
; CHECKBE-NEXT: ret
%x = load i16, ptr %p, align 4
%xz = zext i16 %x to i64
%y = load i32, ptr %q, align 4
%yz = zext i32 %y to i64
%a = and i64 %yz, %xz
%r = and i64 %a, 255
ret i64 %r
}
define i64 @multiple_load_or(ptr %p, ptr %q) {
; CHECK-LABEL: multiple_load_or:
; CHECK: // %bb.0:
; CHECK-NEXT: ldrh w8, [x0]
; CHECK-NEXT: ldr w9, [x1]
; CHECK-NEXT: orr w8, w9, w8
; CHECK-NEXT: and x0, x8, #0xff
; CHECK-NEXT: ret
;
; CHECKBE-LABEL: multiple_load_or:
; CHECKBE: // %bb.0:
; CHECKBE-NEXT: ldrh w8, [x0]
; CHECKBE-NEXT: ldr w9, [x1]
; CHECKBE-NEXT: orr w8, w9, w8
; CHECKBE-NEXT: and x0, x8, #0xff
; CHECKBE-NEXT: ret
%x = load i16, ptr %p, align 4
%xz = zext i16 %x to i64
%y = load i32, ptr %q, align 4
%yz = zext i32 %y to i64
%a = or i64 %yz, %xz
%r = and i64 %a, 255
ret i64 %r
}
define i64 @load32_and16_zexty(ptr %p, i32 %y) {
; CHECK-LABEL: load32_and16_zexty:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr w8, [x0]
; CHECK-NEXT: orr w8, w1, w8
; CHECK-NEXT: and x0, x8, #0xffff
; CHECK-NEXT: ret
;
; CHECKBE-LABEL: load32_and16_zexty:
; CHECKBE: // %bb.0:
; CHECKBE-NEXT: ldr w8, [x0]
; CHECKBE-NEXT: orr w8, w1, w8
; CHECKBE-NEXT: and x0, x8, #0xffff
; CHECKBE-NEXT: ret
%x = load i32, ptr %p, align 4
%xz = zext i32 %x to i64
%yz = zext i32 %y to i64
%a = or i64 %yz, %xz
%r = and i64 %a, 65535
ret i64 %r
}
define i64 @load32_and16_sexty(ptr %p, i32 %y) {
; CHECK-LABEL: load32_and16_sexty:
; CHECK: // %bb.0:
; CHECK-NEXT: ldr w8, [x0]
; CHECK-NEXT: orr w8, w1, w8
; CHECK-NEXT: and x0, x8, #0xffff
; CHECK-NEXT: ret
;
; CHECKBE-LABEL: load32_and16_sexty:
; CHECKBE: // %bb.0:
; CHECKBE-NEXT: ldr w8, [x0]
; CHECKBE-NEXT: orr w8, w1, w8
; CHECKBE-NEXT: and x0, x8, #0xffff
; CHECKBE-NEXT: ret
%x = load i32, ptr %p, align 4
%xz = zext i32 %x to i64
%yz = sext i32 %y to i64
%a = or i64 %yz, %xz
%r = and i64 %a, 65535
ret i64 %r
}
define zeroext i1 @bigger(ptr nocapture readonly %c, ptr nocapture readonly %e, i64 %d, i64 %p1) {
; CHECK-LABEL: bigger:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: ldrb w8, [x1, x2]
; CHECK-NEXT: ldrb w9, [x0, x2]
; CHECK-NEXT: and w10, w3, #0x7
; CHECK-NEXT: mov w11, #8 // =0x8
; CHECK-NEXT: sub w10, w11, w10
; CHECK-NEXT: eor w8, w8, w9
; CHECK-NEXT: mov w9, #5 // =0x5
; CHECK-NEXT: lsr w8, w8, w10
; CHECK-NEXT: tst w8, w9
; CHECK-NEXT: cset w0, eq
; CHECK-NEXT: ret
;
; CHECKBE-LABEL: bigger:
; CHECKBE: // %bb.0: // %entry
; CHECKBE-NEXT: ldrb w8, [x1, x2]
; CHECKBE-NEXT: ldrb w9, [x0, x2]
; CHECKBE-NEXT: and w10, w3, #0x7
; CHECKBE-NEXT: mov w11, #8 // =0x8
; CHECKBE-NEXT: sub w10, w11, w10
; CHECKBE-NEXT: eor w8, w8, w9
; CHECKBE-NEXT: mov w9, #5 // =0x5
; CHECKBE-NEXT: lsr w8, w8, w10
; CHECKBE-NEXT: tst w8, w9
; CHECKBE-NEXT: cset w0, eq
; CHECKBE-NEXT: ret
entry:
%0 = trunc i64 %p1 to i16
%1 = and i16 %0, 7
%sh_prom = sub nuw nsw i16 8, %1
%shl = shl nuw nsw i16 5, %sh_prom
%arrayidx = getelementptr inbounds i8, ptr %c, i64 %d
%2 = load i8, ptr %arrayidx, align 1
%3 = and i16 %shl, 255
%conv2 = zext i16 %3 to i32
%arrayidx3 = getelementptr inbounds i8, ptr %e, i64 %d
%4 = load i8, ptr %arrayidx3, align 1
%5 = xor i8 %4, %2
%6 = zext i8 %5 to i32
%7 = and i32 %6, %conv2
%cmp.not = icmp eq i32 %7, 0
ret i1 %cmp.not
}