; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc -mtriple=armv7-linux-gnueabihf %s -o - | FileCheck %s --check-prefixes=CHECK-COMMON,CHECK-ARM ; RUN: llc -mtriple=armv7eb-linux-gnueabihf %s -o - | FileCheck %s --check-prefixes=CHECK-BE ; RUN: llc -mtriple=thumbv7-linux-gnueabihf %s -o - | FileCheck %s --check-prefixes=CHECK-COMMON,CHECK-THUMB ; RUN: llc -mtriple=thumbv7m %s -o - | FileCheck %s --check-prefixes=CHECK-COMMON,CHECK-THUMB ; RUN: llc -mtriple=thumbv7m -mattr=+strict-align %s -o - | FileCheck %s --check-prefixes=CHECK-COMMON,CHECK-ALIGN ; RUN: llc -mtriple=thumbv6m %s -o - | FileCheck %s --check-prefix=CHECK-V6M @array = weak global [4 x i32] zeroinitializer define i32 @test_lshr_and1(i32 %x) { ; CHECK-COMMON-LABEL: test_lshr_and1: ; CHECK-COMMON: @ %bb.0: @ %entry ; CHECK-COMMON-NEXT: movw r1, :lower16:array ; CHECK-COMMON-NEXT: and r0, r0, #12 ; CHECK-COMMON-NEXT: movt r1, :upper16:array ; CHECK-COMMON-NEXT: ldr r0, [r1, r0] ; CHECK-COMMON-NEXT: bx lr ; ; CHECK-BE-LABEL: test_lshr_and1: ; CHECK-BE: @ %bb.0: @ %entry ; CHECK-BE-NEXT: movw r1, :lower16:array ; CHECK-BE-NEXT: and r0, r0, #12 ; CHECK-BE-NEXT: movt r1, :upper16:array ; CHECK-BE-NEXT: ldr r0, [r1, r0] ; CHECK-BE-NEXT: bx lr ; ; CHECK-V6M-LABEL: test_lshr_and1: ; CHECK-V6M: @ %bb.0: @ %entry ; CHECK-V6M-NEXT: movs r1, #12 ; CHECK-V6M-NEXT: ands r1, r0 ; CHECK-V6M-NEXT: ldr r0, .LCPI0_0 ; CHECK-V6M-NEXT: ldr r0, [r0, r1] ; CHECK-V6M-NEXT: bx lr ; CHECK-V6M-NEXT: .p2align 2 ; CHECK-V6M-NEXT: @ %bb.1: ; CHECK-V6M-NEXT: .LCPI0_0: ; CHECK-V6M-NEXT: .long array entry: %tmp2 = lshr i32 %x, 2 %tmp3 = and i32 %tmp2, 3 %tmp4 = getelementptr [4 x i32], ptr @array, i32 0, i32 %tmp3 %tmp5 = load i32, ptr %tmp4, align 4 ret i32 %tmp5 } define i32 @test_lshr_and2(i32 %x) { ; CHECK-ARM-LABEL: test_lshr_and2: ; CHECK-ARM: @ %bb.0: @ %entry ; CHECK-ARM-NEXT: ubfx r0, r0, #1, #15 ; CHECK-ARM-NEXT: add r0, r0, r0 ; CHECK-ARM-NEXT: bx lr ; ; CHECK-BE-LABEL: test_lshr_and2: ; CHECK-BE: @ %bb.0: @ %entry ; CHECK-BE-NEXT: ubfx r0, r0, #1, #15 ; CHECK-BE-NEXT: add r0, r0, r0 ; CHECK-BE-NEXT: bx lr ; ; CHECK-THUMB-LABEL: test_lshr_and2: ; CHECK-THUMB: @ %bb.0: @ %entry ; CHECK-THUMB-NEXT: ubfx r0, r0, #1, #15 ; CHECK-THUMB-NEXT: add r0, r0 ; CHECK-THUMB-NEXT: bx lr ; ; CHECK-ALIGN-LABEL: test_lshr_and2: ; CHECK-ALIGN: @ %bb.0: @ %entry ; CHECK-ALIGN-NEXT: ubfx r0, r0, #1, #15 ; CHECK-ALIGN-NEXT: add r0, r0 ; CHECK-ALIGN-NEXT: bx lr ; ; CHECK-V6M-LABEL: test_lshr_and2: ; CHECK-V6M: @ %bb.0: @ %entry ; CHECK-V6M-NEXT: lsls r0, r0, #16 ; CHECK-V6M-NEXT: lsrs r0, r0, #17 ; CHECK-V6M-NEXT: adds r0, r0, r0 ; CHECK-V6M-NEXT: bx lr entry: %a = and i32 %x, 65534 %b = lshr i32 %a, 1 %c = and i32 %x, 65535 %d = lshr i32 %c, 1 %e = add i32 %b, %d ret i32 %e } define arm_aapcscc i32 @test_lshr_load1(ptr %a) { ; CHECK-COMMON-LABEL: test_lshr_load1: ; CHECK-COMMON: @ %bb.0: @ %entry ; CHECK-COMMON-NEXT: ldrb r0, [r0, #1] ; CHECK-COMMON-NEXT: bx lr ; ; CHECK-BE-LABEL: test_lshr_load1: ; CHECK-BE: @ %bb.0: @ %entry ; CHECK-BE-NEXT: ldrb r0, [r0] ; CHECK-BE-NEXT: bx lr ; ; CHECK-V6M-LABEL: test_lshr_load1: ; CHECK-V6M: @ %bb.0: @ %entry ; CHECK-V6M-NEXT: ldrb r0, [r0, #1] ; CHECK-V6M-NEXT: bx lr entry: %0 = load i16, ptr %a, align 2 %conv1 = zext i16 %0 to i32 %1 = lshr i32 %conv1, 8 ret i32 %1 } define arm_aapcscc i32 @test_lshr_load1_sext(ptr %a) { ; CHECK-ARM-LABEL: test_lshr_load1_sext: ; CHECK-ARM: @ %bb.0: @ %entry ; CHECK-ARM-NEXT: ldrsh r0, [r0] ; CHECK-ARM-NEXT: lsr r0, r0, #8 ; CHECK-ARM-NEXT: bx lr ; ; CHECK-BE-LABEL: test_lshr_load1_sext: ; CHECK-BE: @ %bb.0: @ %entry ; CHECK-BE-NEXT: ldrsh r0, [r0] ; CHECK-BE-NEXT: lsr r0, r0, #8 ; CHECK-BE-NEXT: bx lr ; ; CHECK-THUMB-LABEL: test_lshr_load1_sext: ; CHECK-THUMB: @ %bb.0: @ %entry ; CHECK-THUMB-NEXT: ldrsh.w r0, [r0] ; CHECK-THUMB-NEXT: lsrs r0, r0, #8 ; CHECK-THUMB-NEXT: bx lr ; ; CHECK-ALIGN-LABEL: test_lshr_load1_sext: ; CHECK-ALIGN: @ %bb.0: @ %entry ; CHECK-ALIGN-NEXT: ldrsh.w r0, [r0] ; CHECK-ALIGN-NEXT: lsrs r0, r0, #8 ; CHECK-ALIGN-NEXT: bx lr ; ; CHECK-V6M-LABEL: test_lshr_load1_sext: ; CHECK-V6M: @ %bb.0: @ %entry ; CHECK-V6M-NEXT: movs r1, #0 ; CHECK-V6M-NEXT: ldrsh r0, [r0, r1] ; CHECK-V6M-NEXT: lsrs r0, r0, #8 ; CHECK-V6M-NEXT: bx lr entry: %0 = load i16, ptr %a, align 2 %conv1 = sext i16 %0 to i32 %1 = lshr i32 %conv1, 8 ret i32 %1 } define arm_aapcscc i32 @test_lshr_load1_fail(ptr %a) { ; CHECK-ARM-LABEL: test_lshr_load1_fail: ; CHECK-ARM: @ %bb.0: @ %entry ; CHECK-ARM-NEXT: ldrh r0, [r0] ; CHECK-ARM-NEXT: lsr r0, r0, #9 ; CHECK-ARM-NEXT: bx lr ; ; CHECK-BE-LABEL: test_lshr_load1_fail: ; CHECK-BE: @ %bb.0: @ %entry ; CHECK-BE-NEXT: ldrh r0, [r0] ; CHECK-BE-NEXT: lsr r0, r0, #9 ; CHECK-BE-NEXT: bx lr ; ; CHECK-THUMB-LABEL: test_lshr_load1_fail: ; CHECK-THUMB: @ %bb.0: @ %entry ; CHECK-THUMB-NEXT: ldrh r0, [r0] ; CHECK-THUMB-NEXT: lsrs r0, r0, #9 ; CHECK-THUMB-NEXT: bx lr ; ; CHECK-ALIGN-LABEL: test_lshr_load1_fail: ; CHECK-ALIGN: @ %bb.0: @ %entry ; CHECK-ALIGN-NEXT: ldrh r0, [r0] ; CHECK-ALIGN-NEXT: lsrs r0, r0, #9 ; CHECK-ALIGN-NEXT: bx lr ; ; CHECK-V6M-LABEL: test_lshr_load1_fail: ; CHECK-V6M: @ %bb.0: @ %entry ; CHECK-V6M-NEXT: ldrh r0, [r0] ; CHECK-V6M-NEXT: lsrs r0, r0, #9 ; CHECK-V6M-NEXT: bx lr entry: %0 = load i16, ptr %a, align 2 %conv1 = zext i16 %0 to i32 %1 = lshr i32 %conv1, 9 ret i32 %1 } define arm_aapcscc i32 @test_lshr_load32(ptr %a) { ; CHECK-ARM-LABEL: test_lshr_load32: ; CHECK-ARM: @ %bb.0: @ %entry ; CHECK-ARM-NEXT: ldr r0, [r0] ; CHECK-ARM-NEXT: lsr r0, r0, #8 ; CHECK-ARM-NEXT: bx lr ; ; CHECK-BE-LABEL: test_lshr_load32: ; CHECK-BE: @ %bb.0: @ %entry ; CHECK-BE-NEXT: ldr r0, [r0] ; CHECK-BE-NEXT: lsr r0, r0, #8 ; CHECK-BE-NEXT: bx lr ; ; CHECK-THUMB-LABEL: test_lshr_load32: ; CHECK-THUMB: @ %bb.0: @ %entry ; CHECK-THUMB-NEXT: ldr r0, [r0] ; CHECK-THUMB-NEXT: lsrs r0, r0, #8 ; CHECK-THUMB-NEXT: bx lr ; ; CHECK-ALIGN-LABEL: test_lshr_load32: ; CHECK-ALIGN: @ %bb.0: @ %entry ; CHECK-ALIGN-NEXT: ldr r0, [r0] ; CHECK-ALIGN-NEXT: lsrs r0, r0, #8 ; CHECK-ALIGN-NEXT: bx lr ; ; CHECK-V6M-LABEL: test_lshr_load32: ; CHECK-V6M: @ %bb.0: @ %entry ; CHECK-V6M-NEXT: ldr r0, [r0] ; CHECK-V6M-NEXT: lsrs r0, r0, #8 ; CHECK-V6M-NEXT: bx lr entry: %0 = load i32, ptr %a, align 4 %1 = lshr i32 %0, 8 ret i32 %1 } define arm_aapcscc i32 @test_lshr_load32_2(ptr %a) { ; CHECK-COMMON-LABEL: test_lshr_load32_2: ; CHECK-COMMON: @ %bb.0: @ %entry ; CHECK-COMMON-NEXT: ldrh r0, [r0, #2] ; CHECK-COMMON-NEXT: bx lr ; ; CHECK-BE-LABEL: test_lshr_load32_2: ; CHECK-BE: @ %bb.0: @ %entry ; CHECK-BE-NEXT: ldrh r0, [r0] ; CHECK-BE-NEXT: bx lr ; ; CHECK-V6M-LABEL: test_lshr_load32_2: ; CHECK-V6M: @ %bb.0: @ %entry ; CHECK-V6M-NEXT: ldrh r0, [r0, #2] ; CHECK-V6M-NEXT: bx lr entry: %0 = load i32, ptr %a, align 4 %1 = lshr i32 %0, 16 ret i32 %1 } define arm_aapcscc i32 @test_lshr_load32_1(ptr %a) { ; CHECK-COMMON-LABEL: test_lshr_load32_1: ; CHECK-COMMON: @ %bb.0: @ %entry ; CHECK-COMMON-NEXT: ldrb r0, [r0, #3] ; CHECK-COMMON-NEXT: bx lr ; ; CHECK-BE-LABEL: test_lshr_load32_1: ; CHECK-BE: @ %bb.0: @ %entry ; CHECK-BE-NEXT: ldrb r0, [r0] ; CHECK-BE-NEXT: bx lr ; ; CHECK-V6M-LABEL: test_lshr_load32_1: ; CHECK-V6M: @ %bb.0: @ %entry ; CHECK-V6M-NEXT: ldrb r0, [r0, #3] ; CHECK-V6M-NEXT: bx lr entry: %0 = load i32, ptr %a, align 4 %1 = lshr i32 %0, 24 ret i32 %1 } define arm_aapcscc i32 @test_lshr_load32_fail(ptr %a) { ; CHECK-ARM-LABEL: test_lshr_load32_fail: ; CHECK-ARM: @ %bb.0: @ %entry ; CHECK-ARM-NEXT: ldr r0, [r0] ; CHECK-ARM-NEXT: lsr r0, r0, #15 ; CHECK-ARM-NEXT: bx lr ; ; CHECK-BE-LABEL: test_lshr_load32_fail: ; CHECK-BE: @ %bb.0: @ %entry ; CHECK-BE-NEXT: ldr r0, [r0] ; CHECK-BE-NEXT: lsr r0, r0, #15 ; CHECK-BE-NEXT: bx lr ; ; CHECK-THUMB-LABEL: test_lshr_load32_fail: ; CHECK-THUMB: @ %bb.0: @ %entry ; CHECK-THUMB-NEXT: ldr r0, [r0] ; CHECK-THUMB-NEXT: lsrs r0, r0, #15 ; CHECK-THUMB-NEXT: bx lr ; ; CHECK-ALIGN-LABEL: test_lshr_load32_fail: ; CHECK-ALIGN: @ %bb.0: @ %entry ; CHECK-ALIGN-NEXT: ldr r0, [r0] ; CHECK-ALIGN-NEXT: lsrs r0, r0, #15 ; CHECK-ALIGN-NEXT: bx lr ; ; CHECK-V6M-LABEL: test_lshr_load32_fail: ; CHECK-V6M: @ %bb.0: @ %entry ; CHECK-V6M-NEXT: ldr r0, [r0] ; CHECK-V6M-NEXT: lsrs r0, r0, #15 ; CHECK-V6M-NEXT: bx lr entry: %0 = load i32, ptr %a, align 4 %1 = lshr i32 %0, 15 ret i32 %1 } define arm_aapcscc i32 @test_lshr_load64_4_unaligned(ptr %a) { ; CHECK-ARM-LABEL: test_lshr_load64_4_unaligned: ; CHECK-ARM: @ %bb.0: @ %entry ; CHECK-ARM-NEXT: ldr r0, [r0, #2] ; CHECK-ARM-NEXT: bx lr ; ; CHECK-BE-LABEL: test_lshr_load64_4_unaligned: ; CHECK-BE: @ %bb.0: @ %entry ; CHECK-BE-NEXT: ldr r0, [r0, #2] ; CHECK-BE-NEXT: bx lr ; ; CHECK-THUMB-LABEL: test_lshr_load64_4_unaligned: ; CHECK-THUMB: @ %bb.0: @ %entry ; CHECK-THUMB-NEXT: ldr.w r0, [r0, #2] ; CHECK-THUMB-NEXT: bx lr ; ; CHECK-ALIGN-LABEL: test_lshr_load64_4_unaligned: ; CHECK-ALIGN: @ %bb.0: @ %entry ; CHECK-ALIGN-NEXT: ldr r1, [r0, #4] ; CHECK-ALIGN-NEXT: ldrh r0, [r0, #2] ; CHECK-ALIGN-NEXT: orr.w r0, r0, r1, lsl #16 ; CHECK-ALIGN-NEXT: bx lr ; ; CHECK-V6M-LABEL: test_lshr_load64_4_unaligned: ; CHECK-V6M: @ %bb.0: @ %entry ; CHECK-V6M-NEXT: ldrh r1, [r0, #2] ; CHECK-V6M-NEXT: ldr r0, [r0, #4] ; CHECK-V6M-NEXT: lsls r0, r0, #16 ; CHECK-V6M-NEXT: adds r0, r1, r0 ; CHECK-V6M-NEXT: bx lr entry: %0 = load i64, ptr %a, align 8 %1 = lshr i64 %0, 16 %conv = trunc i64 %1 to i32 ret i32 %conv } define arm_aapcscc i32 @test_lshr_load64_1_lsb(ptr %a) { ; CHECK-ARM-LABEL: test_lshr_load64_1_lsb: ; CHECK-ARM: @ %bb.0: @ %entry ; CHECK-ARM-NEXT: ldr r0, [r0, #3] ; CHECK-ARM-NEXT: bx lr ; ; CHECK-BE-LABEL: test_lshr_load64_1_lsb: ; CHECK-BE: @ %bb.0: @ %entry ; CHECK-BE-NEXT: ldr r0, [r0, #1] ; CHECK-BE-NEXT: bx lr ; ; CHECK-THUMB-LABEL: test_lshr_load64_1_lsb: ; CHECK-THUMB: @ %bb.0: @ %entry ; CHECK-THUMB-NEXT: ldr.w r0, [r0, #3] ; CHECK-THUMB-NEXT: bx lr ; ; CHECK-ALIGN-LABEL: test_lshr_load64_1_lsb: ; CHECK-ALIGN: @ %bb.0: @ %entry ; CHECK-ALIGN-NEXT: ldr r1, [r0, #4] ; CHECK-ALIGN-NEXT: ldrb r0, [r0, #3] ; CHECK-ALIGN-NEXT: orr.w r0, r0, r1, lsl #8 ; CHECK-ALIGN-NEXT: bx lr ; ; CHECK-V6M-LABEL: test_lshr_load64_1_lsb: ; CHECK-V6M: @ %bb.0: @ %entry ; CHECK-V6M-NEXT: ldrb r1, [r0, #3] ; CHECK-V6M-NEXT: ldr r0, [r0, #4] ; CHECK-V6M-NEXT: lsls r0, r0, #8 ; CHECK-V6M-NEXT: adds r0, r1, r0 ; CHECK-V6M-NEXT: bx lr entry: %0 = load i64, ptr %a, align 8 %1 = lshr i64 %0, 24 %conv = trunc i64 %1 to i32 ret i32 %conv } define arm_aapcscc i32 @test_lshr_load64_1_msb(ptr %a) { ; CHECK-COMMON-LABEL: test_lshr_load64_1_msb: ; CHECK-COMMON: @ %bb.0: @ %entry ; CHECK-COMMON-NEXT: ldrb r0, [r0, #7] ; CHECK-COMMON-NEXT: bx lr ; ; CHECK-BE-LABEL: test_lshr_load64_1_msb: ; CHECK-BE: @ %bb.0: @ %entry ; CHECK-BE-NEXT: ldrb r0, [r0] ; CHECK-BE-NEXT: bx lr ; ; CHECK-V6M-LABEL: test_lshr_load64_1_msb: ; CHECK-V6M: @ %bb.0: @ %entry ; CHECK-V6M-NEXT: ldrb r0, [r0, #7] ; CHECK-V6M-NEXT: bx lr entry: %0 = load i64, ptr %a, align 8 %1 = lshr i64 %0, 56 %conv = trunc i64 %1 to i32 ret i32 %conv } define arm_aapcscc i32 @test_lshr_load64_4(ptr %a) { ; CHECK-COMMON-LABEL: test_lshr_load64_4: ; CHECK-COMMON: @ %bb.0: @ %entry ; CHECK-COMMON-NEXT: ldr r0, [r0, #4] ; CHECK-COMMON-NEXT: bx lr ; ; CHECK-BE-LABEL: test_lshr_load64_4: ; CHECK-BE: @ %bb.0: @ %entry ; CHECK-BE-NEXT: ldr r0, [r0] ; CHECK-BE-NEXT: bx lr ; ; CHECK-V6M-LABEL: test_lshr_load64_4: ; CHECK-V6M: @ %bb.0: @ %entry ; CHECK-V6M-NEXT: ldr r0, [r0, #4] ; CHECK-V6M-NEXT: bx lr entry: %0 = load i64, ptr %a, align 8 %1 = lshr i64 %0, 32 %conv = trunc i64 %1 to i32 ret i32 %conv } define arm_aapcscc i32 @test_lshr_load64_2(ptr %a) { ; CHECK-COMMON-LABEL: test_lshr_load64_2: ; CHECK-COMMON: @ %bb.0: @ %entry ; CHECK-COMMON-NEXT: ldrh r0, [r0, #6] ; CHECK-COMMON-NEXT: bx lr ; ; CHECK-BE-LABEL: test_lshr_load64_2: ; CHECK-BE: @ %bb.0: @ %entry ; CHECK-BE-NEXT: ldrh r0, [r0] ; CHECK-BE-NEXT: bx lr ; ; CHECK-V6M-LABEL: test_lshr_load64_2: ; CHECK-V6M: @ %bb.0: @ %entry ; CHECK-V6M-NEXT: ldrh r0, [r0, #6] ; CHECK-V6M-NEXT: bx lr entry: %0 = load i64, ptr %a, align 8 %1 = lshr i64 %0, 48 %conv = trunc i64 %1 to i32 ret i32 %conv } define arm_aapcscc i32 @test_lshr_load4_fail(ptr %a) { ; CHECK-ARM-LABEL: test_lshr_load4_fail: ; CHECK-ARM: @ %bb.0: @ %entry ; CHECK-ARM-NEXT: ldr r0, [r0, #1] ; CHECK-ARM-NEXT: bx lr ; ; CHECK-BE-LABEL: test_lshr_load4_fail: ; CHECK-BE: @ %bb.0: @ %entry ; CHECK-BE-NEXT: ldr r0, [r0, #3] ; CHECK-BE-NEXT: bx lr ; ; CHECK-THUMB-LABEL: test_lshr_load4_fail: ; CHECK-THUMB: @ %bb.0: @ %entry ; CHECK-THUMB-NEXT: ldr.w r0, [r0, #1] ; CHECK-THUMB-NEXT: bx lr ; ; CHECK-ALIGN-LABEL: test_lshr_load4_fail: ; CHECK-ALIGN: @ %bb.0: @ %entry ; CHECK-ALIGN-NEXT: ldrd r0, r1, [r0] ; CHECK-ALIGN-NEXT: lsrs r0, r0, #8 ; CHECK-ALIGN-NEXT: orr.w r0, r0, r1, lsl #24 ; CHECK-ALIGN-NEXT: bx lr ; ; CHECK-V6M-LABEL: test_lshr_load4_fail: ; CHECK-V6M: @ %bb.0: @ %entry ; CHECK-V6M-NEXT: ldr r1, [r0] ; CHECK-V6M-NEXT: ldr r0, [r0, #4] ; CHECK-V6M-NEXT: lsls r0, r0, #24 ; CHECK-V6M-NEXT: lsrs r1, r1, #8 ; CHECK-V6M-NEXT: adds r0, r1, r0 ; CHECK-V6M-NEXT: bx lr entry: %0 = load i64, ptr %a, align 8 %1 = lshr i64 %0, 8 %conv = trunc i64 %1 to i32 ret i32 %conv } define arm_aapcscc void @test_shift7_mask8(ptr nocapture %p) { ; CHECK-COMMON-LABEL: test_shift7_mask8: ; CHECK-COMMON: @ %bb.0: @ %entry ; CHECK-COMMON-NEXT: ldr r1, [r0] ; CHECK-COMMON-NEXT: ubfx r1, r1, #7, #8 ; CHECK-COMMON-NEXT: str r1, [r0] ; CHECK-COMMON-NEXT: bx lr ; ; CHECK-BE-LABEL: test_shift7_mask8: ; CHECK-BE: @ %bb.0: @ %entry ; CHECK-BE-NEXT: ldr r1, [r0] ; CHECK-BE-NEXT: ubfx r1, r1, #7, #8 ; CHECK-BE-NEXT: str r1, [r0] ; CHECK-BE-NEXT: bx lr ; ; CHECK-V6M-LABEL: test_shift7_mask8: ; CHECK-V6M: @ %bb.0: @ %entry ; CHECK-V6M-NEXT: ldr r1, [r0] ; CHECK-V6M-NEXT: lsrs r1, r1, #7 ; CHECK-V6M-NEXT: uxtb r1, r1 ; CHECK-V6M-NEXT: str r1, [r0] ; CHECK-V6M-NEXT: bx lr entry: %0 = load i32, ptr %p, align 4 %shl = lshr i32 %0, 7 %and = and i32 %shl, 255 store i32 %and, ptr %p, align 4 ret void } define arm_aapcscc void @test_shift8_mask8(ptr nocapture %p) { ; CHECK-COMMON-LABEL: test_shift8_mask8: ; CHECK-COMMON: @ %bb.0: @ %entry ; CHECK-COMMON-NEXT: ldrb r1, [r0, #1] ; CHECK-COMMON-NEXT: str r1, [r0] ; CHECK-COMMON-NEXT: bx lr ; ; CHECK-BE-LABEL: test_shift8_mask8: ; CHECK-BE: @ %bb.0: @ %entry ; CHECK-BE-NEXT: ldrb r1, [r0, #2] ; CHECK-BE-NEXT: str r1, [r0] ; CHECK-BE-NEXT: bx lr ; ; CHECK-V6M-LABEL: test_shift8_mask8: ; CHECK-V6M: @ %bb.0: @ %entry ; CHECK-V6M-NEXT: ldrb r1, [r0, #1] ; CHECK-V6M-NEXT: str r1, [r0] ; CHECK-V6M-NEXT: bx lr entry: %0 = load i32, ptr %p, align 4 %shl = lshr i32 %0, 8 %and = and i32 %shl, 255 store i32 %and, ptr %p, align 4 ret void } define arm_aapcscc void @test_shift8_mask7(ptr nocapture %p) { ; CHECK-COMMON-LABEL: test_shift8_mask7: ; CHECK-COMMON: @ %bb.0: @ %entry ; CHECK-COMMON-NEXT: ldr r1, [r0] ; CHECK-COMMON-NEXT: ubfx r1, r1, #8, #7 ; CHECK-COMMON-NEXT: str r1, [r0] ; CHECK-COMMON-NEXT: bx lr ; ; CHECK-BE-LABEL: test_shift8_mask7: ; CHECK-BE: @ %bb.0: @ %entry ; CHECK-BE-NEXT: ldr r1, [r0] ; CHECK-BE-NEXT: ubfx r1, r1, #8, #7 ; CHECK-BE-NEXT: str r1, [r0] ; CHECK-BE-NEXT: bx lr ; ; CHECK-V6M-LABEL: test_shift8_mask7: ; CHECK-V6M: @ %bb.0: @ %entry ; CHECK-V6M-NEXT: ldr r1, [r0] ; CHECK-V6M-NEXT: lsls r1, r1, #17 ; CHECK-V6M-NEXT: lsrs r1, r1, #25 ; CHECK-V6M-NEXT: str r1, [r0] ; CHECK-V6M-NEXT: bx lr entry: %0 = load i32, ptr %p, align 4 %shl = lshr i32 %0, 8 %and = and i32 %shl, 127 store i32 %and, ptr %p, align 4 ret void } define arm_aapcscc void @test_shift9_mask8(ptr nocapture %p) { ; CHECK-COMMON-LABEL: test_shift9_mask8: ; CHECK-COMMON: @ %bb.0: @ %entry ; CHECK-COMMON-NEXT: ldr r1, [r0] ; CHECK-COMMON-NEXT: ubfx r1, r1, #9, #8 ; CHECK-COMMON-NEXT: str r1, [r0] ; CHECK-COMMON-NEXT: bx lr ; ; CHECK-BE-LABEL: test_shift9_mask8: ; CHECK-BE: @ %bb.0: @ %entry ; CHECK-BE-NEXT: ldr r1, [r0] ; CHECK-BE-NEXT: ubfx r1, r1, #9, #8 ; CHECK-BE-NEXT: str r1, [r0] ; CHECK-BE-NEXT: bx lr ; ; CHECK-V6M-LABEL: test_shift9_mask8: ; CHECK-V6M: @ %bb.0: @ %entry ; CHECK-V6M-NEXT: ldr r1, [r0] ; CHECK-V6M-NEXT: lsrs r1, r1, #9 ; CHECK-V6M-NEXT: uxtb r1, r1 ; CHECK-V6M-NEXT: str r1, [r0] ; CHECK-V6M-NEXT: bx lr entry: %0 = load i32, ptr %p, align 4 %shl = lshr i32 %0, 9 %and = and i32 %shl, 255 store i32 %and, ptr %p, align 4 ret void } define arm_aapcscc void @test_shift8_mask16(ptr nocapture %p) { ; CHECK-ARM-LABEL: test_shift8_mask16: ; CHECK-ARM: @ %bb.0: @ %entry ; CHECK-ARM-NEXT: ldrh r1, [r0, #1] ; CHECK-ARM-NEXT: str r1, [r0] ; CHECK-ARM-NEXT: bx lr ; ; CHECK-BE-LABEL: test_shift8_mask16: ; CHECK-BE: @ %bb.0: @ %entry ; CHECK-BE-NEXT: ldrh r1, [r0, #1] ; CHECK-BE-NEXT: str r1, [r0] ; CHECK-BE-NEXT: bx lr ; ; CHECK-THUMB-LABEL: test_shift8_mask16: ; CHECK-THUMB: @ %bb.0: @ %entry ; CHECK-THUMB-NEXT: ldrh.w r1, [r0, #1] ; CHECK-THUMB-NEXT: str r1, [r0] ; CHECK-THUMB-NEXT: bx lr ; ; CHECK-ALIGN-LABEL: test_shift8_mask16: ; CHECK-ALIGN: @ %bb.0: @ %entry ; CHECK-ALIGN-NEXT: ldr r1, [r0] ; CHECK-ALIGN-NEXT: ubfx r1, r1, #8, #16 ; CHECK-ALIGN-NEXT: str r1, [r0] ; CHECK-ALIGN-NEXT: bx lr ; ; CHECK-V6M-LABEL: test_shift8_mask16: ; CHECK-V6M: @ %bb.0: @ %entry ; CHECK-V6M-NEXT: ldr r1, [r0] ; CHECK-V6M-NEXT: lsrs r1, r1, #8 ; CHECK-V6M-NEXT: uxth r1, r1 ; CHECK-V6M-NEXT: str r1, [r0] ; CHECK-V6M-NEXT: bx lr entry: %0 = load i32, ptr %p, align 4 %shl = lshr i32 %0, 8 %and = and i32 %shl, 65535 store i32 %and, ptr %p, align 4 ret void } define arm_aapcscc void @test_shift15_mask16(ptr nocapture %p) { ; CHECK-COMMON-LABEL: test_shift15_mask16: ; CHECK-COMMON: @ %bb.0: @ %entry ; CHECK-COMMON-NEXT: ldr r1, [r0] ; CHECK-COMMON-NEXT: ubfx r1, r1, #15, #16 ; CHECK-COMMON-NEXT: str r1, [r0] ; CHECK-COMMON-NEXT: bx lr ; ; CHECK-BE-LABEL: test_shift15_mask16: ; CHECK-BE: @ %bb.0: @ %entry ; CHECK-BE-NEXT: ldr r1, [r0] ; CHECK-BE-NEXT: ubfx r1, r1, #15, #16 ; CHECK-BE-NEXT: str r1, [r0] ; CHECK-BE-NEXT: bx lr ; ; CHECK-V6M-LABEL: test_shift15_mask16: ; CHECK-V6M: @ %bb.0: @ %entry ; CHECK-V6M-NEXT: ldr r1, [r0] ; CHECK-V6M-NEXT: lsrs r1, r1, #15 ; CHECK-V6M-NEXT: uxth r1, r1 ; CHECK-V6M-NEXT: str r1, [r0] ; CHECK-V6M-NEXT: bx lr entry: %0 = load i32, ptr %p, align 4 %shl = lshr i32 %0, 15 %and = and i32 %shl, 65535 store i32 %and, ptr %p, align 4 ret void } define arm_aapcscc void @test_shift16_mask15(ptr nocapture %p) { ; CHECK-COMMON-LABEL: test_shift16_mask15: ; CHECK-COMMON: @ %bb.0: @ %entry ; CHECK-COMMON-NEXT: ldrh r1, [r0, #2] ; CHECK-COMMON-NEXT: bfc r1, #15, #17 ; CHECK-COMMON-NEXT: str r1, [r0] ; CHECK-COMMON-NEXT: bx lr ; ; CHECK-BE-LABEL: test_shift16_mask15: ; CHECK-BE: @ %bb.0: @ %entry ; CHECK-BE-NEXT: ldrh r1, [r0] ; CHECK-BE-NEXT: bfc r1, #15, #17 ; CHECK-BE-NEXT: str r1, [r0] ; CHECK-BE-NEXT: bx lr ; ; CHECK-V6M-LABEL: test_shift16_mask15: ; CHECK-V6M: @ %bb.0: @ %entry ; CHECK-V6M-NEXT: ldrh r1, [r0, #2] ; CHECK-V6M-NEXT: ldr r2, .LCPI21_0 ; CHECK-V6M-NEXT: ands r2, r1 ; CHECK-V6M-NEXT: str r2, [r0] ; CHECK-V6M-NEXT: bx lr ; CHECK-V6M-NEXT: .p2align 2 ; CHECK-V6M-NEXT: @ %bb.1: ; CHECK-V6M-NEXT: .LCPI21_0: ; CHECK-V6M-NEXT: .long 32767 @ 0x7fff entry: %0 = load i32, ptr %p, align 4 %shl = lshr i32 %0, 16 %and = and i32 %shl, 32767 store i32 %and, ptr %p, align 4 ret void } define arm_aapcscc void @test_shift8_mask24(ptr nocapture %p) { ; CHECK-ARM-LABEL: test_shift8_mask24: ; CHECK-ARM: @ %bb.0: @ %entry ; CHECK-ARM-NEXT: ldr r1, [r0] ; CHECK-ARM-NEXT: lsr r1, r1, #8 ; CHECK-ARM-NEXT: str r1, [r0] ; CHECK-ARM-NEXT: bx lr ; ; CHECK-BE-LABEL: test_shift8_mask24: ; CHECK-BE: @ %bb.0: @ %entry ; CHECK-BE-NEXT: ldr r1, [r0] ; CHECK-BE-NEXT: lsr r1, r1, #8 ; CHECK-BE-NEXT: str r1, [r0] ; CHECK-BE-NEXT: bx lr ; ; CHECK-THUMB-LABEL: test_shift8_mask24: ; CHECK-THUMB: @ %bb.0: @ %entry ; CHECK-THUMB-NEXT: ldr r1, [r0] ; CHECK-THUMB-NEXT: lsrs r1, r1, #8 ; CHECK-THUMB-NEXT: str r1, [r0] ; CHECK-THUMB-NEXT: bx lr ; ; CHECK-ALIGN-LABEL: test_shift8_mask24: ; CHECK-ALIGN: @ %bb.0: @ %entry ; CHECK-ALIGN-NEXT: ldr r1, [r0] ; CHECK-ALIGN-NEXT: lsrs r1, r1, #8 ; CHECK-ALIGN-NEXT: str r1, [r0] ; CHECK-ALIGN-NEXT: bx lr ; ; CHECK-V6M-LABEL: test_shift8_mask24: ; CHECK-V6M: @ %bb.0: @ %entry ; CHECK-V6M-NEXT: ldr r1, [r0] ; CHECK-V6M-NEXT: lsrs r1, r1, #8 ; CHECK-V6M-NEXT: str r1, [r0] ; CHECK-V6M-NEXT: bx lr entry: %0 = load i32, ptr %p, align 4 %shl = lshr i32 %0, 8 %and = and i32 %shl, 16777215 store i32 %and, ptr %p, align 4 ret void } define arm_aapcscc void @test_shift24_mask16(ptr nocapture %p) { ; CHECK-COMMON-LABEL: test_shift24_mask16: ; CHECK-COMMON: @ %bb.0: @ %entry ; CHECK-COMMON-NEXT: ldrb r1, [r0, #3] ; CHECK-COMMON-NEXT: str r1, [r0] ; CHECK-COMMON-NEXT: bx lr ; ; CHECK-BE-LABEL: test_shift24_mask16: ; CHECK-BE: @ %bb.0: @ %entry ; CHECK-BE-NEXT: ldrb r1, [r0] ; CHECK-BE-NEXT: str r1, [r0] ; CHECK-BE-NEXT: bx lr ; ; CHECK-V6M-LABEL: test_shift24_mask16: ; CHECK-V6M: @ %bb.0: @ %entry ; CHECK-V6M-NEXT: ldrb r1, [r0, #3] ; CHECK-V6M-NEXT: str r1, [r0] ; CHECK-V6M-NEXT: bx lr entry: %0 = load i32, ptr %p, align 4 %shl = lshr i32 %0, 24 %and = and i32 %shl, 65535 store i32 %and, ptr %p, align 4 ret void } define arm_aapcscc void @test_sext_shift8_mask8(ptr %p, ptr %q) { ; CHECK-COMMON-LABEL: test_sext_shift8_mask8: ; CHECK-COMMON: @ %bb.0: @ %entry ; CHECK-COMMON-NEXT: ldrb r0, [r0, #1] ; CHECK-COMMON-NEXT: str r0, [r1] ; CHECK-COMMON-NEXT: bx lr ; ; CHECK-BE-LABEL: test_sext_shift8_mask8: ; CHECK-BE: @ %bb.0: @ %entry ; CHECK-BE-NEXT: ldrb r0, [r0] ; CHECK-BE-NEXT: str r0, [r1] ; CHECK-BE-NEXT: bx lr ; ; CHECK-V6M-LABEL: test_sext_shift8_mask8: ; CHECK-V6M: @ %bb.0: @ %entry ; CHECK-V6M-NEXT: ldrb r0, [r0, #1] ; CHECK-V6M-NEXT: str r0, [r1] ; CHECK-V6M-NEXT: bx lr entry: %0 = load i16, ptr %p, align 4 %1 = sext i16 %0 to i32 %shl = lshr i32 %1, 8 %and = and i32 %shl, 255 store i32 %and, ptr %q, align 4 ret void } define arm_aapcscc void @test_sext_shift8_mask16(ptr %p, ptr %q) { ; CHECK-ARM-LABEL: test_sext_shift8_mask16: ; CHECK-ARM: @ %bb.0: @ %entry ; CHECK-ARM-NEXT: ldrsh r0, [r0] ; CHECK-ARM-NEXT: ubfx r0, r0, #8, #16 ; CHECK-ARM-NEXT: str r0, [r1] ; CHECK-ARM-NEXT: bx lr ; ; CHECK-BE-LABEL: test_sext_shift8_mask16: ; CHECK-BE: @ %bb.0: @ %entry ; CHECK-BE-NEXT: ldrsh r0, [r0] ; CHECK-BE-NEXT: ubfx r0, r0, #8, #16 ; CHECK-BE-NEXT: str r0, [r1] ; CHECK-BE-NEXT: bx lr ; ; CHECK-THUMB-LABEL: test_sext_shift8_mask16: ; CHECK-THUMB: @ %bb.0: @ %entry ; CHECK-THUMB-NEXT: ldrsh.w r0, [r0] ; CHECK-THUMB-NEXT: ubfx r0, r0, #8, #16 ; CHECK-THUMB-NEXT: str r0, [r1] ; CHECK-THUMB-NEXT: bx lr ; ; CHECK-ALIGN-LABEL: test_sext_shift8_mask16: ; CHECK-ALIGN: @ %bb.0: @ %entry ; CHECK-ALIGN-NEXT: ldrsh.w r0, [r0] ; CHECK-ALIGN-NEXT: ubfx r0, r0, #8, #16 ; CHECK-ALIGN-NEXT: str r0, [r1] ; CHECK-ALIGN-NEXT: bx lr ; ; CHECK-V6M-LABEL: test_sext_shift8_mask16: ; CHECK-V6M: @ %bb.0: @ %entry ; CHECK-V6M-NEXT: movs r2, #0 ; CHECK-V6M-NEXT: ldrsh r0, [r0, r2] ; CHECK-V6M-NEXT: lsrs r0, r0, #8 ; CHECK-V6M-NEXT: uxth r0, r0 ; CHECK-V6M-NEXT: str r0, [r1] ; CHECK-V6M-NEXT: bx lr entry: %0 = load i16, ptr %p, align 4 %1 = sext i16 %0 to i32 %shl = lshr i32 %1, 8 %and = and i32 %shl, 65535 store i32 %and, ptr %q, align 4 ret void } define i1 @trunc_i64_mask_srl(i32 zeroext %AttrArgNo, ptr %ptr) { ; CHECK-ARM-LABEL: trunc_i64_mask_srl: ; CHECK-ARM: @ %bb.0: @ %entry ; CHECK-ARM-NEXT: ldrh r2, [r1, #4] ; CHECK-ARM-NEXT: mov r1, #0 ; CHECK-ARM-NEXT: cmp r2, r0 ; CHECK-ARM-NEXT: movwhi r1, #1 ; CHECK-ARM-NEXT: mov r0, r1 ; CHECK-ARM-NEXT: bx lr ; ; CHECK-BE-LABEL: trunc_i64_mask_srl: ; CHECK-BE: @ %bb.0: @ %entry ; CHECK-BE-NEXT: ldrh r2, [r1, #2] ; CHECK-BE-NEXT: mov r1, #0 ; CHECK-BE-NEXT: cmp r2, r0 ; CHECK-BE-NEXT: movwhi r1, #1 ; CHECK-BE-NEXT: mov r0, r1 ; CHECK-BE-NEXT: bx lr ; ; CHECK-THUMB-LABEL: trunc_i64_mask_srl: ; CHECK-THUMB: @ %bb.0: @ %entry ; CHECK-THUMB-NEXT: ldrh r2, [r1, #4] ; CHECK-THUMB-NEXT: movs r1, #0 ; CHECK-THUMB-NEXT: cmp r2, r0 ; CHECK-THUMB-NEXT: it hi ; CHECK-THUMB-NEXT: movhi r1, #1 ; CHECK-THUMB-NEXT: mov r0, r1 ; CHECK-THUMB-NEXT: bx lr ; ; CHECK-ALIGN-LABEL: trunc_i64_mask_srl: ; CHECK-ALIGN: @ %bb.0: @ %entry ; CHECK-ALIGN-NEXT: ldrh r2, [r1, #4] ; CHECK-ALIGN-NEXT: movs r1, #0 ; CHECK-ALIGN-NEXT: cmp r2, r0 ; CHECK-ALIGN-NEXT: it hi ; CHECK-ALIGN-NEXT: movhi r1, #1 ; CHECK-ALIGN-NEXT: mov r0, r1 ; CHECK-ALIGN-NEXT: bx lr ; ; CHECK-V6M-LABEL: trunc_i64_mask_srl: ; CHECK-V6M: @ %bb.0: @ %entry ; CHECK-V6M-NEXT: ldrh r1, [r1, #4] ; CHECK-V6M-NEXT: cmp r1, r0 ; CHECK-V6M-NEXT: bhi .LBB26_2 ; CHECK-V6M-NEXT: @ %bb.1: @ %entry ; CHECK-V6M-NEXT: movs r0, #0 ; CHECK-V6M-NEXT: bx lr ; CHECK-V6M-NEXT: .LBB26_2: ; CHECK-V6M-NEXT: movs r0, #1 ; CHECK-V6M-NEXT: bx lr entry: %bf.load.i = load i64, ptr %ptr, align 8 %bf.lshr.i = lshr i64 %bf.load.i, 32 %0 = trunc i64 %bf.lshr.i to i32 %bf.cast.i = and i32 %0, 65535 %cmp.i = icmp ugt i32 %bf.cast.i, %AttrArgNo ret i1 %cmp.i } define i64 @or_tree_with_shifts_i64(i64 %a, i64 %b, i64 %c, i64 %d) { ; CHECK-ARM-LABEL: or_tree_with_shifts_i64: ; CHECK-ARM: @ %bb.0: ; CHECK-ARM-NEXT: .save {r11, lr} ; CHECK-ARM-NEXT: push {r11, lr} ; CHECK-ARM-NEXT: ldr lr, [sp, #16] ; CHECK-ARM-NEXT: orr r0, r0, r2, lsl #16 ; CHECK-ARM-NEXT: ldr r12, [sp, #8] ; CHECK-ARM-NEXT: orr r3, lr, r3 ; CHECK-ARM-NEXT: orr r1, r1, r3, lsl #16 ; CHECK-ARM-NEXT: orr r1, r1, r2, lsr #16 ; CHECK-ARM-NEXT: orr r1, r1, r12 ; CHECK-ARM-NEXT: pop {r11, pc} ; ; CHECK-BE-LABEL: or_tree_with_shifts_i64: ; CHECK-BE: @ %bb.0: ; CHECK-BE-NEXT: .save {r11, lr} ; CHECK-BE-NEXT: push {r11, lr} ; CHECK-BE-NEXT: ldr lr, [sp, #20] ; CHECK-BE-NEXT: orr r1, r1, r3, lsl #16 ; CHECK-BE-NEXT: ldr r12, [sp, #12] ; CHECK-BE-NEXT: orr r2, lr, r2 ; CHECK-BE-NEXT: orr r0, r0, r2, lsl #16 ; CHECK-BE-NEXT: orr r0, r0, r3, lsr #16 ; CHECK-BE-NEXT: orr r0, r0, r12 ; CHECK-BE-NEXT: pop {r11, pc} ; ; CHECK-ALIGN-LABEL: or_tree_with_shifts_i64: ; CHECK-ALIGN: @ %bb.0: ; CHECK-ALIGN-NEXT: ldr.w r12, [sp, #8] ; CHECK-ALIGN-NEXT: orr.w r0, r0, r2, lsl #16 ; CHECK-ALIGN-NEXT: orr.w r3, r3, r12 ; CHECK-ALIGN-NEXT: orr.w r1, r1, r3, lsl #16 ; CHECK-ALIGN-NEXT: orr.w r1, r1, r2, lsr #16 ; CHECK-ALIGN-NEXT: ldr r2, [sp] ; CHECK-ALIGN-NEXT: orrs r1, r2 ; CHECK-ALIGN-NEXT: bx lr ; ; CHECK-V6M-LABEL: or_tree_with_shifts_i64: ; CHECK-V6M: @ %bb.0: ; CHECK-V6M-NEXT: push {r4, lr} ; CHECK-V6M-NEXT: lsls r4, r2, #16 ; CHECK-V6M-NEXT: orrs r0, r4 ; CHECK-V6M-NEXT: ldr r4, [sp, #16] ; CHECK-V6M-NEXT: orrs r4, r3 ; CHECK-V6M-NEXT: lsls r3, r4, #16 ; CHECK-V6M-NEXT: orrs r1, r3 ; CHECK-V6M-NEXT: lsrs r2, r2, #16 ; CHECK-V6M-NEXT: orrs r1, r2 ; CHECK-V6M-NEXT: ldr r2, [sp, #8] ; CHECK-V6M-NEXT: orrs r1, r2 ; CHECK-V6M-NEXT: pop {r4, pc} %b.shifted = shl i64 %b, 16 %c.shifted = shl i64 %c, 32 %d.shifted = shl i64 %d, 48 %or.ad = or i64 %a, %d.shifted %or.adb = or i64 %or.ad, %b.shifted %or.adbc = or i64 %or.adb, %c.shifted ret i64 %or.adbc } define i32 @or_tree_with_shifts_i32(i32 %a, i32 %b, i32 %c, i32 %d) { ; CHECK-ARM-LABEL: or_tree_with_shifts_i32: ; CHECK-ARM: @ %bb.0: ; CHECK-ARM-NEXT: orr r0, r0, r2 ; CHECK-ARM-NEXT: orr r0, r1, r0, lsl #16 ; CHECK-ARM-NEXT: orr r0, r0, r3 ; CHECK-ARM-NEXT: bx lr ; ; CHECK-BE-LABEL: or_tree_with_shifts_i32: ; CHECK-BE: @ %bb.0: ; CHECK-BE-NEXT: orr r0, r0, r2 ; CHECK-BE-NEXT: orr r0, r1, r0, lsl #16 ; CHECK-BE-NEXT: orr r0, r0, r3 ; CHECK-BE-NEXT: bx lr ; ; CHECK-THUMB-LABEL: or_tree_with_shifts_i32: ; CHECK-THUMB: @ %bb.0: ; CHECK-THUMB-NEXT: orrs r0, r2 ; CHECK-THUMB-NEXT: orr.w r0, r1, r0, lsl #16 ; CHECK-THUMB-NEXT: orrs r0, r3 ; CHECK-THUMB-NEXT: bx lr ; ; CHECK-ALIGN-LABEL: or_tree_with_shifts_i32: ; CHECK-ALIGN: @ %bb.0: ; CHECK-ALIGN-NEXT: orrs r0, r2 ; CHECK-ALIGN-NEXT: orr.w r0, r1, r0, lsl #16 ; CHECK-ALIGN-NEXT: orrs r0, r3 ; CHECK-ALIGN-NEXT: bx lr ; ; CHECK-V6M-LABEL: or_tree_with_shifts_i32: ; CHECK-V6M: @ %bb.0: ; CHECK-V6M-NEXT: orrs r0, r2 ; CHECK-V6M-NEXT: lsls r0, r0, #16 ; CHECK-V6M-NEXT: orrs r0, r1 ; CHECK-V6M-NEXT: orrs r0, r3 ; CHECK-V6M-NEXT: bx lr %a.shifted = shl i32 %a, 16 %c.shifted = shl i32 %c, 16 %or.ab = or i32 %a.shifted, %b %or.cd = or i32 %c.shifted, %d %r = or i32 %or.ab, %or.cd ret i32 %r } define i32 @xor_tree_with_shifts_i32(i32 %a, i32 %b, i32 %c, i32 %d) { ; CHECK-ARM-LABEL: xor_tree_with_shifts_i32: ; CHECK-ARM: @ %bb.0: ; CHECK-ARM-NEXT: eor r0, r0, r2 ; CHECK-ARM-NEXT: eor r0, r1, r0, lsr #16 ; CHECK-ARM-NEXT: eor r0, r0, r3 ; CHECK-ARM-NEXT: bx lr ; ; CHECK-BE-LABEL: xor_tree_with_shifts_i32: ; CHECK-BE: @ %bb.0: ; CHECK-BE-NEXT: eor r0, r0, r2 ; CHECK-BE-NEXT: eor r0, r1, r0, lsr #16 ; CHECK-BE-NEXT: eor r0, r0, r3 ; CHECK-BE-NEXT: bx lr ; ; CHECK-THUMB-LABEL: xor_tree_with_shifts_i32: ; CHECK-THUMB: @ %bb.0: ; CHECK-THUMB-NEXT: eors r0, r2 ; CHECK-THUMB-NEXT: eor.w r0, r1, r0, lsr #16 ; CHECK-THUMB-NEXT: eors r0, r3 ; CHECK-THUMB-NEXT: bx lr ; ; CHECK-ALIGN-LABEL: xor_tree_with_shifts_i32: ; CHECK-ALIGN: @ %bb.0: ; CHECK-ALIGN-NEXT: eors r0, r2 ; CHECK-ALIGN-NEXT: eor.w r0, r1, r0, lsr #16 ; CHECK-ALIGN-NEXT: eors r0, r3 ; CHECK-ALIGN-NEXT: bx lr ; ; CHECK-V6M-LABEL: xor_tree_with_shifts_i32: ; CHECK-V6M: @ %bb.0: ; CHECK-V6M-NEXT: eors r0, r2 ; CHECK-V6M-NEXT: lsrs r0, r0, #16 ; CHECK-V6M-NEXT: eors r0, r1 ; CHECK-V6M-NEXT: eors r0, r3 ; CHECK-V6M-NEXT: bx lr %a.shifted = lshr i32 %a, 16 %c.shifted = lshr i32 %c, 16 %xor.ab = xor i32 %a.shifted, %b %xor.cd = xor i32 %d, %c.shifted %r = xor i32 %xor.ab, %xor.cd ret i32 %r } define i32 @and_tree_with_shifts_i32(i32 %a, i32 %b, i32 %c, i32 %d) { ; CHECK-ARM-LABEL: and_tree_with_shifts_i32: ; CHECK-ARM: @ %bb.0: ; CHECK-ARM-NEXT: and r0, r0, r2 ; CHECK-ARM-NEXT: and r0, r1, r0, asr #16 ; CHECK-ARM-NEXT: and r0, r0, r3 ; CHECK-ARM-NEXT: bx lr ; ; CHECK-BE-LABEL: and_tree_with_shifts_i32: ; CHECK-BE: @ %bb.0: ; CHECK-BE-NEXT: and r0, r0, r2 ; CHECK-BE-NEXT: and r0, r1, r0, asr #16 ; CHECK-BE-NEXT: and r0, r0, r3 ; CHECK-BE-NEXT: bx lr ; ; CHECK-THUMB-LABEL: and_tree_with_shifts_i32: ; CHECK-THUMB: @ %bb.0: ; CHECK-THUMB-NEXT: ands r0, r2 ; CHECK-THUMB-NEXT: and.w r0, r1, r0, asr #16 ; CHECK-THUMB-NEXT: ands r0, r3 ; CHECK-THUMB-NEXT: bx lr ; ; CHECK-ALIGN-LABEL: and_tree_with_shifts_i32: ; CHECK-ALIGN: @ %bb.0: ; CHECK-ALIGN-NEXT: ands r0, r2 ; CHECK-ALIGN-NEXT: and.w r0, r1, r0, asr #16 ; CHECK-ALIGN-NEXT: ands r0, r3 ; CHECK-ALIGN-NEXT: bx lr ; ; CHECK-V6M-LABEL: and_tree_with_shifts_i32: ; CHECK-V6M: @ %bb.0: ; CHECK-V6M-NEXT: ands r0, r2 ; CHECK-V6M-NEXT: asrs r0, r0, #16 ; CHECK-V6M-NEXT: ands r0, r1 ; CHECK-V6M-NEXT: ands r0, r3 ; CHECK-V6M-NEXT: bx lr %a.shifted = ashr i32 %a, 16 %c.shifted = ashr i32 %c, 16 %and.ab = and i32 %b, %a.shifted %and.cd = and i32 %c.shifted, %d %r = and i32 %and.ab, %and.cd ret i32 %r } define i32 @logic_tree_with_shifts_var_i32(i32 %a, i32 %b, i32 %c, i32 %d, i32 %s) { ; CHECK-ARM-LABEL: logic_tree_with_shifts_var_i32: ; CHECK-ARM: @ %bb.0: ; CHECK-ARM-NEXT: ldr r12, [sp] ; CHECK-ARM-NEXT: orr r0, r0, r2 ; CHECK-ARM-NEXT: orr r0, r1, r0, lsl r12 ; CHECK-ARM-NEXT: orr r0, r0, r3 ; CHECK-ARM-NEXT: bx lr ; ; CHECK-BE-LABEL: logic_tree_with_shifts_var_i32: ; CHECK-BE: @ %bb.0: ; CHECK-BE-NEXT: ldr r12, [sp] ; CHECK-BE-NEXT: orr r0, r0, r2 ; CHECK-BE-NEXT: orr r0, r1, r0, lsl r12 ; CHECK-BE-NEXT: orr r0, r0, r3 ; CHECK-BE-NEXT: bx lr ; ; CHECK-ALIGN-LABEL: logic_tree_with_shifts_var_i32: ; CHECK-ALIGN: @ %bb.0: ; CHECK-ALIGN-NEXT: orrs r0, r2 ; CHECK-ALIGN-NEXT: ldr r2, [sp] ; CHECK-ALIGN-NEXT: lsls r0, r2 ; CHECK-ALIGN-NEXT: orrs r0, r1 ; CHECK-ALIGN-NEXT: orrs r0, r3 ; CHECK-ALIGN-NEXT: bx lr ; ; CHECK-V6M-LABEL: logic_tree_with_shifts_var_i32: ; CHECK-V6M: @ %bb.0: ; CHECK-V6M-NEXT: orrs r0, r2 ; CHECK-V6M-NEXT: ldr r2, [sp] ; CHECK-V6M-NEXT: lsls r0, r2 ; CHECK-V6M-NEXT: orrs r0, r1 ; CHECK-V6M-NEXT: orrs r0, r3 ; CHECK-V6M-NEXT: bx lr %a.shifted = shl i32 %a, %s %c.shifted = shl i32 %c, %s %or.ab = or i32 %b, %a.shifted %or.cd = or i32 %d, %c.shifted %r = or i32 %or.ab, %or.cd ret i32 %r } define i32 @logic_tree_with_mismatching_shifts_i32(i32 %a, i32 %b, i32 %c, i32 %d) { ; CHECK-ARM-LABEL: logic_tree_with_mismatching_shifts_i32: ; CHECK-ARM: @ %bb.0: ; CHECK-ARM-NEXT: orr r2, r3, r2, lsl #16 ; CHECK-ARM-NEXT: orr r0, r1, r0, lsl #15 ; CHECK-ARM-NEXT: orr r0, r0, r2 ; CHECK-ARM-NEXT: bx lr ; ; CHECK-BE-LABEL: logic_tree_with_mismatching_shifts_i32: ; CHECK-BE: @ %bb.0: ; CHECK-BE-NEXT: orr r2, r3, r2, lsl #16 ; CHECK-BE-NEXT: orr r0, r1, r0, lsl #15 ; CHECK-BE-NEXT: orr r0, r0, r2 ; CHECK-BE-NEXT: bx lr ; ; CHECK-THUMB-LABEL: logic_tree_with_mismatching_shifts_i32: ; CHECK-THUMB: @ %bb.0: ; CHECK-THUMB-NEXT: orr.w r2, r3, r2, lsl #16 ; CHECK-THUMB-NEXT: orr.w r0, r1, r0, lsl #15 ; CHECK-THUMB-NEXT: orrs r0, r2 ; CHECK-THUMB-NEXT: bx lr ; ; CHECK-ALIGN-LABEL: logic_tree_with_mismatching_shifts_i32: ; CHECK-ALIGN: @ %bb.0: ; CHECK-ALIGN-NEXT: orr.w r2, r3, r2, lsl #16 ; CHECK-ALIGN-NEXT: orr.w r0, r1, r0, lsl #15 ; CHECK-ALIGN-NEXT: orrs r0, r2 ; CHECK-ALIGN-NEXT: bx lr ; ; CHECK-V6M-LABEL: logic_tree_with_mismatching_shifts_i32: ; CHECK-V6M: @ %bb.0: ; CHECK-V6M-NEXT: lsls r2, r2, #16 ; CHECK-V6M-NEXT: orrs r2, r3 ; CHECK-V6M-NEXT: lsls r0, r0, #15 ; CHECK-V6M-NEXT: orrs r0, r1 ; CHECK-V6M-NEXT: orrs r0, r2 ; CHECK-V6M-NEXT: bx lr %a.shifted = shl i32 %a, 15 %c.shifted = shl i32 %c, 16 %or.ab = or i32 %a.shifted, %b %or.cd = or i32 %c.shifted, %d %r = or i32 %or.ab, %or.cd ret i32 %r } define i32 @logic_tree_with_mismatching_shifts2_i32(i32 %a, i32 %b, i32 %c, i32 %d) { ; CHECK-ARM-LABEL: logic_tree_with_mismatching_shifts2_i32: ; CHECK-ARM: @ %bb.0: ; CHECK-ARM-NEXT: orr r2, r3, r2, lsr #16 ; CHECK-ARM-NEXT: orr r0, r1, r0, lsl #16 ; CHECK-ARM-NEXT: orr r0, r0, r2 ; CHECK-ARM-NEXT: bx lr ; ; CHECK-BE-LABEL: logic_tree_with_mismatching_shifts2_i32: ; CHECK-BE: @ %bb.0: ; CHECK-BE-NEXT: orr r2, r3, r2, lsr #16 ; CHECK-BE-NEXT: orr r0, r1, r0, lsl #16 ; CHECK-BE-NEXT: orr r0, r0, r2 ; CHECK-BE-NEXT: bx lr ; ; CHECK-THUMB-LABEL: logic_tree_with_mismatching_shifts2_i32: ; CHECK-THUMB: @ %bb.0: ; CHECK-THUMB-NEXT: orr.w r2, r3, r2, lsr #16 ; CHECK-THUMB-NEXT: orr.w r0, r1, r0, lsl #16 ; CHECK-THUMB-NEXT: orrs r0, r2 ; CHECK-THUMB-NEXT: bx lr ; ; CHECK-ALIGN-LABEL: logic_tree_with_mismatching_shifts2_i32: ; CHECK-ALIGN: @ %bb.0: ; CHECK-ALIGN-NEXT: orr.w r2, r3, r2, lsr #16 ; CHECK-ALIGN-NEXT: orr.w r0, r1, r0, lsl #16 ; CHECK-ALIGN-NEXT: orrs r0, r2 ; CHECK-ALIGN-NEXT: bx lr ; ; CHECK-V6M-LABEL: logic_tree_with_mismatching_shifts2_i32: ; CHECK-V6M: @ %bb.0: ; CHECK-V6M-NEXT: lsrs r2, r2, #16 ; CHECK-V6M-NEXT: orrs r2, r3 ; CHECK-V6M-NEXT: lsls r0, r0, #16 ; CHECK-V6M-NEXT: orrs r0, r1 ; CHECK-V6M-NEXT: orrs r0, r2 ; CHECK-V6M-NEXT: bx lr %a.shifted = shl i32 %a, 16 %c.shifted = lshr i32 %c, 16 %or.ab = or i32 %a.shifted, %b %or.cd = or i32 %c.shifted, %d %r = or i32 %or.ab, %or.cd ret i32 %r } define <4 x i32> @or_tree_with_shifts_vec_i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c, <4 x i32> %d) { ; CHECK-ARM-LABEL: or_tree_with_shifts_vec_i32: ; CHECK-ARM: @ %bb.0: ; CHECK-ARM-NEXT: vorr q8, q0, q2 ; CHECK-ARM-NEXT: vshl.i32 q8, q8, #16 ; CHECK-ARM-NEXT: vorr q8, q8, q1 ; CHECK-ARM-NEXT: vorr q0, q8, q3 ; CHECK-ARM-NEXT: bx lr ; ; CHECK-BE-LABEL: or_tree_with_shifts_vec_i32: ; CHECK-BE: @ %bb.0: ; CHECK-BE-NEXT: vrev64.32 q8, q2 ; CHECK-BE-NEXT: vrev64.32 q9, q0 ; CHECK-BE-NEXT: vorr q8, q9, q8 ; CHECK-BE-NEXT: vrev64.32 q9, q1 ; CHECK-BE-NEXT: vrev64.32 q10, q3 ; CHECK-BE-NEXT: vshl.i32 q8, q8, #16 ; CHECK-BE-NEXT: vorr q8, q8, q9 ; CHECK-BE-NEXT: vorr q8, q8, q10 ; CHECK-BE-NEXT: vrev64.32 q0, q8 ; CHECK-BE-NEXT: bx lr %a.shifted = shl <4 x i32> %a, %c.shifted = shl <4 x i32> %c, %or.ab = or <4 x i32> %a.shifted, %b %or.cd = or <4 x i32> %c.shifted, %d %r = or <4 x i32> %or.ab, %or.cd ret <4 x i32> %r } define <4 x i32> @or_tree_with_mismatching_shifts_vec_i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c, <4 x i32> %d) { ; CHECK-ARM-LABEL: or_tree_with_mismatching_shifts_vec_i32: ; CHECK-ARM: @ %bb.0: ; CHECK-ARM-NEXT: vshl.i32 q8, q2, #17 ; CHECK-ARM-NEXT: vshl.i32 q9, q0, #16 ; CHECK-ARM-NEXT: vorr q8, q8, q3 ; CHECK-ARM-NEXT: vorr q9, q9, q1 ; CHECK-ARM-NEXT: vorr q0, q9, q8 ; CHECK-ARM-NEXT: bx lr ; ; CHECK-BE-LABEL: or_tree_with_mismatching_shifts_vec_i32: ; CHECK-BE: @ %bb.0: ; CHECK-BE-NEXT: vrev64.32 q8, q2 ; CHECK-BE-NEXT: vrev64.32 q9, q0 ; CHECK-BE-NEXT: vshl.i32 q8, q8, #17 ; CHECK-BE-NEXT: vrev64.32 q10, q3 ; CHECK-BE-NEXT: vshl.i32 q9, q9, #16 ; CHECK-BE-NEXT: vrev64.32 q11, q1 ; CHECK-BE-NEXT: vorr q8, q8, q10 ; CHECK-BE-NEXT: vorr q9, q9, q11 ; CHECK-BE-NEXT: vorr q8, q9, q8 ; CHECK-BE-NEXT: vrev64.32 q0, q8 ; CHECK-BE-NEXT: bx lr %a.shifted = shl <4 x i32> %a, %c.shifted = shl <4 x i32> %c, %or.ab = or <4 x i32> %a.shifted, %b %or.cd = or <4 x i32> %c.shifted, %d %r = or <4 x i32> %or.ab, %or.cd ret <4 x i32> %r }