1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
; RUN: llc -mtriple=arm64-apple-macosx -o - %s | FileCheck %s
%struct.zot = type { ptr, i32, ptr, ptr, i32, i32, i32, i32, i32, i32 }
; FIXME: currently the AND is performed on 64 bit unnecessarily.
; Test cases where an AND is extended from i32 -> i64 which is free. Make
; sure the extends do not get moved to the arguments, which would perform the
; AND on 64 bits unnecessarily.
define void @avoid_promotion_1_and(ptr nocapture noundef %arg, ptr %p) {
; CHECK-LABEL: avoid_promotion_1_and:
; CHECK: ; %bb.0: ; %bb
; CHECK-NEXT: ldr w8, [x0, #52]
; CHECK-NEXT: mov w9, #10 ; =0xa
; CHECK-NEXT: LBB0_1: ; %bb8
; CHECK-NEXT: ; =>This Inner Loop Header: Depth=1
; CHECK-NEXT: cmp w8, #3
; CHECK-NEXT: b.lo LBB0_1
; CHECK-NEXT: ; %bb.2: ; %bb9
; CHECK-NEXT: ; in Loop: Header=BB0_1 Depth=1
; CHECK-NEXT: ldr w10, [x0, #32]
; CHECK-NEXT: ldr w11, [x1, #76]
; CHECK-NEXT: ldr w12, [x1]
; CHECK-NEXT: eor w10, w10, w11
; CHECK-NEXT: and w10, w10, w12
; CHECK-NEXT: str w10, [x0, #32]
; CHECK-NEXT: strh w9, [x1, w10, uxtw #1]
; CHECK-NEXT: b LBB0_1
bb:
%gep = getelementptr inbounds %struct.zot, ptr %arg, i64 0, i32 9
%l = load i32, ptr %gep, align 4
%icmp = icmp ugt i32 %l, 2
%gep1 = getelementptr inbounds %struct.zot, ptr %arg, i64 0, i32 4
%gep2 = getelementptr inbounds %struct.zot, ptr %arg, i64 0, i32 7
br label %bb8
bb8: ; preds = %bb27, %bb
br i1 %icmp, label %bb9, label %bb27
bb9: ; preds = %bb8
%l10 = load i32, ptr %gep1, align 8
%gep14 = getelementptr inbounds i32, ptr %p, i64 19
%l15 = load i32, ptr %gep14, align 1
%xor = xor i32 %l10, %l15
%l17 = load i32, ptr %p, align 8
%and = and i32 %xor, %l17
store i32 %and, ptr %gep1, align 8
%zext19 = zext i32 %and to i64
%gep20 = getelementptr inbounds i16, ptr %p, i64 %zext19
store i16 10, ptr %gep20, align 2
br label %bb27
bb27: ; preds = %bb9, %bb8
br label %bb8
}
define void @avoid_promotion_2_and(ptr nocapture noundef %arg) {
; CHECK-LABEL: avoid_promotion_2_and:
; CHECK: ; %bb.0: ; %entry
; CHECK-NEXT: add x8, x0, #32
; CHECK-NEXT: b LBB1_2
; CHECK-NEXT: LBB1_1: ; %latch
; CHECK-NEXT: ; in Loop: Header=BB1_2 Depth=1
; CHECK-NEXT: cmp w9, #2
; CHECK-NEXT: add x8, x8, #56
; CHECK-NEXT: b.ls LBB1_4
; CHECK-NEXT: LBB1_2: ; %loop
; CHECK-NEXT: ; =>This Inner Loop Header: Depth=1
; CHECK-NEXT: ldr w9, [x8, #20]
; CHECK-NEXT: cmp w9, #3
; CHECK-NEXT: b.lo LBB1_1
; CHECK-NEXT: ; %bb.3: ; %then
; CHECK-NEXT: ; in Loop: Header=BB1_2 Depth=1
; CHECK-NEXT: ldp w13, w12, [x8, #12]
; CHECK-NEXT: ldr w10, [x8]
; CHECK-NEXT: ldr x11, [x0]
; CHECK-NEXT: ldr w14, [x8, #8]
; CHECK-NEXT: lsl w10, w10, w13
; CHECK-NEXT: ldrb w11, [x11, x12]
; CHECK-NEXT: eor w10, w10, w11
; CHECK-NEXT: ldur w11, [x8, #-24]
; CHECK-NEXT: and w10, w10, w14
; CHECK-NEXT: ldp x14, x13, [x8, #-16]
; CHECK-NEXT: str w10, [x8]
; CHECK-NEXT: and w11, w11, w12
; CHECK-NEXT: ldrh w15, [x13, w10, uxtw #1]
; CHECK-NEXT: strh w15, [x14, w11, uxtw #1]
; CHECK-NEXT: strh w12, [x13, w10, uxtw #1]
; CHECK-NEXT: b LBB1_1
; CHECK-NEXT: LBB1_4: ; %exit
; CHECK-NEXT: ret
entry:
br label %loop
loop:
%p = phi i64 [ 0, %entry ], [ %p.next, %latch ]
%gep = getelementptr inbounds %struct.zot, ptr %arg, i64 %p, i32 9
%l = load i32, ptr %gep, align 4
%icmp = icmp ugt i32 %l, 2
%gep1 = getelementptr inbounds %struct.zot, ptr %arg, i64 %p, i32 4
%gep2 = getelementptr inbounds %struct.zot, ptr %arg, i64 %p, i32 7
%gep3 = getelementptr inbounds %struct.zot, ptr %arg, i64 %p, i32 8
%gep4 = getelementptr inbounds %struct.zot, ptr %arg, i64 %p, i32 6
%gep5 = getelementptr inbounds %struct.zot, ptr %arg, i64 %p, i32 3
%gep6 = getelementptr inbounds %struct.zot, ptr %arg, i64 %p, i32 2
%gep7 = getelementptr inbounds %struct.zot, ptr %arg, i64 %p, i32 1
br i1 %icmp, label %then, label %latch
then:
%l10 = load i32, ptr %gep1, align 8
%l11 = load i32, ptr %gep2, align 4
%shl = shl i32 %l10, %l11
%l12 = load ptr, ptr %arg, align 8
%l13 = load i32, ptr %gep3, align 8
%zext = zext i32 %l13 to i64
%gep14 = getelementptr inbounds i8, ptr %l12, i64 %zext
%l15 = load i8, ptr %gep14, align 1
%zext16 = zext i8 %l15 to i32
%xor = xor i32 %shl, %zext16
%l17 = load i32, ptr %gep4, align 8
%and = and i32 %xor, %l17
store i32 %and, ptr %gep1, align 8
%l18 = load ptr, ptr %gep5, align 8
%zext19 = zext i32 %and to i64
%gep20 = getelementptr inbounds i16, ptr %l18, i64 %zext19
%l21 = load i16, ptr %gep20, align 2
%l22 = load ptr, ptr %gep6, align 8
%l23 = load i32, ptr %gep7, align 8
%and24 = and i32 %l23, %l13
%zext25 = zext i32 %and24 to i64
%gep26 = getelementptr inbounds i16, ptr %l22, i64 %zext25
store i16 %l21, ptr %gep26, align 2
%trunc = trunc i32 %l13 to i16
store i16 %trunc, ptr %gep20, align 2
br label %latch
latch:
%p.next = add i64 %p, 1
br i1 %icmp, label %loop, label %exit
exit:
ret void
}
|