[llvm] 6c52f82 - [X86][ARM] Add tests for bitwise logic trees of shifts; NFC

Filipp Zhinkin via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 8 11:09:25 PDT 2022


Author: Filipp Zhinkin
Date: 2022-08-08T21:09:14+03:00
New Revision: 6c52f82d77a1b8d9d9f8b585c73f94e58191b5a9

URL: https://github.com/llvm/llvm-project/commit/6c52f82d77a1b8d9d9f8b585c73f94e58191b5a9
DIFF: https://github.com/llvm/llvm-project/commit/6c52f82d77a1b8d9d9f8b585c73f94e58191b5a9.diff

LOG: [X86][ARM] Add tests for bitwise logic trees of shifts; NFC

Baseline tests for D131189.

Added: 
    

Modified: 
    llvm/test/CodeGen/ARM/shift-combine.ll
    llvm/test/CodeGen/X86/shift-combine.ll

Removed: 
    


################################################################################
diff  --git a/llvm/test/CodeGen/ARM/shift-combine.ll b/llvm/test/CodeGen/ARM/shift-combine.ll
index 549d709f62237..d0bd44ec8e8ba 100644
--- a/llvm/test/CodeGen/ARM/shift-combine.ll
+++ b/llvm/test/CodeGen/ARM/shift-combine.ll
@@ -893,3 +893,410 @@ entry:
   %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:    lsl r3, r3, #16
+; CHECK-ARM-NEXT:    ldr r12, [sp, #8]
+; CHECK-ARM-NEXT:    orr r3, r3, r2, lsr #16
+; CHECK-ARM-NEXT:    orr r0, r0, r2, lsl #16
+; CHECK-ARM-NEXT:    orr r1, r1, lr, lsl #16
+; CHECK-ARM-NEXT:    orr r1, r1, r3
+; 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:    lsl r2, r2, #16
+; CHECK-BE-NEXT:    ldr r12, [sp, #12]
+; CHECK-BE-NEXT:    orr r2, r2, r3, lsr #16
+; CHECK-BE-NEXT:    orr r1, r1, r3, lsl #16
+; CHECK-BE-NEXT:    orr r0, r0, lr, lsl #16
+; CHECK-BE-NEXT:    orr r0, r0, r2
+; 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:    lsls r3, r3, #16
+; CHECK-ALIGN-NEXT:    orr.w r3, r3, r2, lsr #16
+; CHECK-ALIGN-NEXT:    orr.w r0, r0, r2, lsl #16
+; CHECK-ALIGN-NEXT:    orr.w r1, r1, r12, lsl #16
+; CHECK-ALIGN-NEXT:    orrs r1, r3
+; CHECK-ALIGN-NEXT:    ldr r3, [sp]
+; CHECK-ALIGN-NEXT:    orrs r1, r3
+; 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:    lsrs r4, r2, #16
+; CHECK-V6M-NEXT:    lsls r3, r3, #16
+; CHECK-V6M-NEXT:    adds r3, r3, r4
+; CHECK-V6M-NEXT:    ldr r4, [sp, #16]
+; CHECK-V6M-NEXT:    lsls r4, r4, #16
+; CHECK-V6M-NEXT:    orrs r1, r4
+; CHECK-V6M-NEXT:    orrs r1, r3
+; CHECK-V6M-NEXT:    ldr r3, [sp, #8]
+; CHECK-V6M-NEXT:    orrs r1, r3
+; CHECK-V6M-NEXT:    lsls r2, r2, #16
+; CHECK-V6M-NEXT:    orrs r0, 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 r2, r3, r2, lsl #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: or_tree_with_shifts_i32:
+; CHECK-BE:       @ %bb.0:
+; CHECK-BE-NEXT:    orr r2, r3, r2, lsl #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: or_tree_with_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 #16
+; CHECK-THUMB-NEXT:    orrs r0, r2
+; CHECK-THUMB-NEXT:    bx lr
+;
+; CHECK-ALIGN-LABEL: or_tree_with_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 #16
+; CHECK-ALIGN-NEXT:    orrs r0, r2
+; CHECK-ALIGN-NEXT:    bx lr
+;
+; CHECK-V6M-LABEL: or_tree_with_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, #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 = 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 r2, r3, r2, lsr #16
+; CHECK-ARM-NEXT:    eor r0, r1, r0, lsr #16
+; CHECK-ARM-NEXT:    eor r0, r0, r2
+; CHECK-ARM-NEXT:    bx lr
+;
+; CHECK-BE-LABEL: xor_tree_with_shifts_i32:
+; CHECK-BE:       @ %bb.0:
+; CHECK-BE-NEXT:    eor r2, r3, r2, lsr #16
+; CHECK-BE-NEXT:    eor r0, r1, r0, lsr #16
+; CHECK-BE-NEXT:    eor r0, r0, r2
+; CHECK-BE-NEXT:    bx lr
+;
+; CHECK-THUMB-LABEL: xor_tree_with_shifts_i32:
+; CHECK-THUMB:       @ %bb.0:
+; CHECK-THUMB-NEXT:    eor.w r2, r3, r2, lsr #16
+; CHECK-THUMB-NEXT:    eor.w r0, r1, r0, lsr #16
+; CHECK-THUMB-NEXT:    eors r0, r2
+; CHECK-THUMB-NEXT:    bx lr
+;
+; CHECK-ALIGN-LABEL: xor_tree_with_shifts_i32:
+; CHECK-ALIGN:       @ %bb.0:
+; CHECK-ALIGN-NEXT:    eor.w r2, r3, r2, lsr #16
+; CHECK-ALIGN-NEXT:    eor.w r0, r1, r0, lsr #16
+; CHECK-ALIGN-NEXT:    eors r0, r2
+; CHECK-ALIGN-NEXT:    bx lr
+;
+; CHECK-V6M-LABEL: xor_tree_with_shifts_i32:
+; CHECK-V6M:       @ %bb.0:
+; CHECK-V6M-NEXT:    lsrs r2, r2, #16
+; CHECK-V6M-NEXT:    eors r2, r3
+; CHECK-V6M-NEXT:    lsrs r0, r0, #16
+; CHECK-V6M-NEXT:    eors r0, r1
+; CHECK-V6M-NEXT:    eors r0, r2
+; 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 %c.shifted, %d
+  %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 r2, r3, r2, asr #16
+; CHECK-ARM-NEXT:    and r0, r1, r0, asr #16
+; CHECK-ARM-NEXT:    and r0, r0, r2
+; CHECK-ARM-NEXT:    bx lr
+;
+; CHECK-BE-LABEL: and_tree_with_shifts_i32:
+; CHECK-BE:       @ %bb.0:
+; CHECK-BE-NEXT:    and r2, r3, r2, asr #16
+; CHECK-BE-NEXT:    and r0, r1, r0, asr #16
+; CHECK-BE-NEXT:    and r0, r0, r2
+; CHECK-BE-NEXT:    bx lr
+;
+; CHECK-THUMB-LABEL: and_tree_with_shifts_i32:
+; CHECK-THUMB:       @ %bb.0:
+; CHECK-THUMB-NEXT:    and.w r2, r3, r2, asr #16
+; CHECK-THUMB-NEXT:    and.w r0, r1, r0, asr #16
+; CHECK-THUMB-NEXT:    ands r0, r2
+; CHECK-THUMB-NEXT:    bx lr
+;
+; CHECK-ALIGN-LABEL: and_tree_with_shifts_i32:
+; CHECK-ALIGN:       @ %bb.0:
+; CHECK-ALIGN-NEXT:    and.w r2, r3, r2, asr #16
+; CHECK-ALIGN-NEXT:    and.w r0, r1, r0, asr #16
+; CHECK-ALIGN-NEXT:    ands r0, r2
+; CHECK-ALIGN-NEXT:    bx lr
+;
+; CHECK-V6M-LABEL: and_tree_with_shifts_i32:
+; CHECK-V6M:       @ %bb.0:
+; CHECK-V6M-NEXT:    asrs r2, r2, #16
+; CHECK-V6M-NEXT:    ands r2, r3
+; CHECK-V6M-NEXT:    asrs r0, r0, #16
+; CHECK-V6M-NEXT:    ands r0, r1
+; CHECK-V6M-NEXT:    ands r0, r2
+; CHECK-V6M-NEXT:    bx lr
+  %a.shifted = ashr i32 %a, 16
+  %c.shifted = ashr i32 %c, 16
+  %and.ab = and i32 %a.shifted, %b
+  %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 r2, r3, r2, lsl r12
+; CHECK-ARM-NEXT:    orr r0, r1, r0, lsl r12
+; CHECK-ARM-NEXT:    orr r0, r0, r2
+; 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 r2, r3, r2, lsl r12
+; CHECK-BE-NEXT:    orr r0, r1, r0, lsl r12
+; CHECK-BE-NEXT:    orr r0, r0, r2
+; CHECK-BE-NEXT:    bx lr
+;
+; CHECK-THUMB-LABEL: logic_tree_with_shifts_var_i32:
+; CHECK-THUMB:       @ %bb.0:
+; CHECK-THUMB-NEXT:    ldr.w r12, [sp]
+; CHECK-THUMB-NEXT:    lsl.w r2, r2, r12
+; CHECK-THUMB-NEXT:    lsl.w r0, r0, r12
+; CHECK-THUMB-NEXT:    orrs r2, r3
+; CHECK-THUMB-NEXT:    orrs r0, r1
+; CHECK-THUMB-NEXT:    orrs r0, r2
+; CHECK-THUMB-NEXT:    bx lr
+;
+; CHECK-ALIGN-LABEL: logic_tree_with_shifts_var_i32:
+; CHECK-ALIGN:       @ %bb.0:
+; CHECK-ALIGN-NEXT:    ldr.w r12, [sp]
+; CHECK-ALIGN-NEXT:    lsl.w r2, r2, r12
+; CHECK-ALIGN-NEXT:    lsl.w r0, r0, r12
+; CHECK-ALIGN-NEXT:    orrs r2, r3
+; CHECK-ALIGN-NEXT:    orrs r0, r1
+; CHECK-ALIGN-NEXT:    orrs r0, r2
+; CHECK-ALIGN-NEXT:    bx lr
+;
+; CHECK-V6M-LABEL: logic_tree_with_shifts_var_i32:
+; CHECK-V6M:       @ %bb.0:
+; CHECK-V6M-NEXT:    push {r4, lr}
+; CHECK-V6M-NEXT:    ldr r4, [sp, #8]
+; CHECK-V6M-NEXT:    lsls r2, r4
+; CHECK-V6M-NEXT:    orrs r2, r3
+; CHECK-V6M-NEXT:    lsls r0, r4
+; CHECK-V6M-NEXT:    orrs r0, r1
+; CHECK-V6M-NEXT:    orrs r0, r2
+; CHECK-V6M-NEXT:    pop {r4, pc}
+  %a.shifted = shl i32 %a, %s
+  %c.shifted = shl i32 %c, %s
+  %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_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:    vshl.i32 q8, q2, #16
+; 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_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, #16
+; 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, <i32 16, i32 16, i32 16, i32 16>
+  %c.shifted = shl <4 x i32> %c, <i32 16, i32 16, i32 16, i32 16>
+  %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, <i32 16, i32 16, i32 16, i32 16>
+  %c.shifted = shl <4 x i32> %c, <i32 17, i32 17, i32 17, i32 17>
+  %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
+}

diff  --git a/llvm/test/CodeGen/X86/shift-combine.ll b/llvm/test/CodeGen/X86/shift-combine.ll
index 8f51cfd26240e..5bfaa2f3f6c48 100644
--- a/llvm/test/CodeGen/X86/shift-combine.ll
+++ b/llvm/test/CodeGen/X86/shift-combine.ll
@@ -506,3 +506,208 @@ define <4 x i32> @ashr_add_neg_shl_v4i8(<4 x i32> %r) nounwind {
   %conv1 = ashr <4 x i32> %sext, <i32 24, i32 24, i32 24, i32 24>
   ret <4 x i32> %conv1
 }
+
+define i32 @or_tree_with_shifts_i32(i32 %a, i32 %b, i32 %c, i32 %d) {
+; X32-LABEL: or_tree_with_shifts_i32:
+; X32:       # %bb.0:
+; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT:    shll $16, %ecx
+; X32-NEXT:    shll $16, %eax
+; X32-NEXT:    orl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT:    orl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    orl %ecx, %eax
+; X32-NEXT:    retl
+;
+; X64-LABEL: or_tree_with_shifts_i32:
+; X64:       # %bb.0:
+; X64-NEXT:    movl %edx, %eax
+; X64-NEXT:    shll $16, %edi
+; X64-NEXT:    shll $16, %eax
+; X64-NEXT:    orl %ecx, %eax
+; X64-NEXT:    orl %esi, %eax
+; X64-NEXT:    orl %edi, %eax
+; X64-NEXT:    retq
+  %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) {
+; X32-LABEL: xor_tree_with_shifts_i32:
+; X32:       # %bb.0:
+; X32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT:    xorl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT:    xorl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    xorl %ecx, %eax
+; X32-NEXT:    retl
+;
+; X64-LABEL: xor_tree_with_shifts_i32:
+; X64:       # %bb.0:
+; X64-NEXT:    movl %edx, %eax
+; X64-NEXT:    shrl $16, %edi
+; X64-NEXT:    shrl $16, %eax
+; X64-NEXT:    xorl %ecx, %eax
+; X64-NEXT:    xorl %esi, %eax
+; X64-NEXT:    xorl %edi, %eax
+; X64-NEXT:    retq
+  %a.shifted = lshr i32 %a, 16
+  %c.shifted = lshr i32 %c, 16
+  %xor.ab = xor i32 %a.shifted, %b
+  %xor.cd = xor i32 %c.shifted, %d
+  %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) {
+; X32-LABEL: and_tree_with_shifts_i32:
+; X32:       # %bb.0:
+; X32-NEXT:    movswl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    movswl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT:    andl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT:    andl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    andl %ecx, %eax
+; X32-NEXT:    retl
+;
+; X64-LABEL: and_tree_with_shifts_i32:
+; X64:       # %bb.0:
+; X64-NEXT:    movl %edx, %eax
+; X64-NEXT:    sarl $16, %edi
+; X64-NEXT:    sarl $16, %eax
+; X64-NEXT:    andl %ecx, %eax
+; X64-NEXT:    andl %esi, %eax
+; X64-NEXT:    andl %edi, %eax
+; X64-NEXT:    retq
+  %a.shifted = ashr i32 %a, 16
+  %c.shifted = ashr i32 %c, 16
+  %and.ab = and i32 %a.shifted, %b
+  %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) {
+; X32-LABEL: logic_tree_with_shifts_var_i32:
+; X32:       # %bb.0:
+; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; X32-NEXT:    shll %cl, %edx
+; X32-NEXT:    shll %cl, %eax
+; X32-NEXT:    orl {{[0-9]+}}(%esp), %edx
+; X32-NEXT:    orl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    orl %edx, %eax
+; X32-NEXT:    retl
+;
+; X64-LABEL: logic_tree_with_shifts_var_i32:
+; X64:       # %bb.0:
+; X64-NEXT:    movl %ecx, %eax
+; X64-NEXT:    movl %r8d, %ecx
+; X64-NEXT:    shll %cl, %edi
+; X64-NEXT:    shll %cl, %edx
+; X64-NEXT:    orl %edx, %eax
+; X64-NEXT:    orl %esi, %eax
+; X64-NEXT:    orl %edi, %eax
+; X64-NEXT:    retq
+  %a.shifted = shl i32 %a, %s
+  %c.shifted = shl i32 %c, %s
+  %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_shifts_i32(i32 %a, i32 %b, i32 %c, i32 %d) {
+; X32-LABEL: logic_tree_with_mismatching_shifts_i32:
+; X32:       # %bb.0:
+; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT:    shll $15, %ecx
+; X32-NEXT:    shll $16, %eax
+; X32-NEXT:    orl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT:    orl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    orl %ecx, %eax
+; X32-NEXT:    retl
+;
+; X64-LABEL: logic_tree_with_mismatching_shifts_i32:
+; X64:       # %bb.0:
+; X64-NEXT:    movl %edx, %eax
+; X64-NEXT:    shll $15, %edi
+; X64-NEXT:    shll $16, %eax
+; X64-NEXT:    orl %ecx, %eax
+; X64-NEXT:    orl %esi, %eax
+; X64-NEXT:    orl %edi, %eax
+; X64-NEXT:    retq
+  %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) {
+; X32-LABEL: logic_tree_with_mismatching_shifts2_i32:
+; X32:       # %bb.0:
+; X32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT:    shll $16, %ecx
+; X32-NEXT:    orl {{[0-9]+}}(%esp), %ecx
+; X32-NEXT:    orl {{[0-9]+}}(%esp), %eax
+; X32-NEXT:    orl %ecx, %eax
+; X32-NEXT:    retl
+;
+; X64-LABEL: logic_tree_with_mismatching_shifts2_i32:
+; X64:       # %bb.0:
+; X64-NEXT:    movl %edx, %eax
+; X64-NEXT:    shll $16, %edi
+; X64-NEXT:    shrl $16, %eax
+; X64-NEXT:    orl %ecx, %eax
+; X64-NEXT:    orl %esi, %eax
+; X64-NEXT:    orl %edi, %eax
+; X64-NEXT:    retq
+  %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) {
+; X64-LABEL: or_tree_with_shifts_vec_i32:
+; X64:       # %bb.0:
+; X64-NEXT:    pslld $16, %xmm0
+; X64-NEXT:    pslld $16, %xmm2
+; X64-NEXT:    por %xmm3, %xmm2
+; X64-NEXT:    por %xmm1, %xmm2
+; X64-NEXT:    por %xmm2, %xmm0
+; X64-NEXT:    retq
+  %a.shifted = shl <4 x i32> %a, <i32 16, i32 16, i32 16, i32 16>
+  %c.shifted = shl <4 x i32> %c, <i32 16, i32 16, i32 16, i32 16>
+  %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) {
+; X64-LABEL: or_tree_with_mismatching_shifts_vec_i32:
+; X64:       # %bb.0:
+; X64-NEXT:    pslld $16, %xmm0
+; X64-NEXT:    pslld $17, %xmm2
+; X64-NEXT:    por %xmm3, %xmm2
+; X64-NEXT:    por %xmm1, %xmm2
+; X64-NEXT:    por %xmm2, %xmm0
+; X64-NEXT:    retq
+  %a.shifted = shl <4 x i32> %a, <i32 16, i32 16, i32 16, i32 16>
+  %c.shifted = shl <4 x i32> %c, <i32 17, i32 17, i32 17, i32 17>
+  %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
+}


        


More information about the llvm-commits mailing list