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
146
|
; 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 x15, x14, [x8, #-16]
; CHECK-NEXT: ubfiz x13, x10, #1, #32
; CHECK-NEXT: str w10, [x8]
; CHECK-NEXT: and w10, w11, w12
; CHECK-NEXT: ldrh w11, [x14, x13]
; CHECK-NEXT: strh w11, [x15, w10, uxtw #1]
; CHECK-NEXT: strh w12, [x14, x13]
; 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
}
|