xref: /llvm-project/llvm/test/CodeGen/AArch64/bfis-in-loop.ll (revision 40d952b8748bf5c4a97fc82296e1fc050388472f)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: opt -mtriple=aarch64-linux-gnu -passes=typepromotion < %s | llc -mtriple=aarch64-linux-gnu -o - | FileCheck %s
3
4target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
5
6%struct.bar = type { %struct.foo }
7%struct.foo = type { ptr }
8%struct.wobble = type { ptr }
9%struct.zot = type <{ %struct.wobble, ptr, ptr, i8, [7 x i8] }>
10
11@global = external global %struct.bar, align 8
12
13define i64 @bfis_in_loop_zero() {
14; CHECK-LABEL: bfis_in_loop_zero:
15; CHECK:       // %bb.0: // %entry
16; CHECK-NEXT: 	adrp	x8, :got:global
17; CHECK-NEXT: 	mov	x0, xzr
18; CHECK-NEXT: 	mov	w9, wzr
19; CHECK-NEXT: 	ldr	x8, [x8, :got_lo12:global]
20; CHECK-NEXT: 	ldr	x8, [x8]
21; CHECK-NEXT: .LBB0_1:                                // %midblock
22; CHECK-NEXT:   // =>This Inner Loop Header: Depth=1
23; CHECK-NEXT:	ldrh	w10, [x8, #72]
24; CHECK-NEXT:	ldr	x13, [x8, #8]
25; CHECK-NEXT:	lsr	w11, w10, #8
26; CHECK-NEXT:	cmp	w10, #0
27; CHECK-NEXT:	ldr	x8, [x13, #16]
28; CHECK-NEXT:	cset	w12, ne
29; CHECK-NEXT:	csel	w9, w9, w11, eq
30; CHECK-NEXT:	and	x11, x0, #0xffffffff00000000
31; CHECK-NEXT:	bfi	w10, w9, #8, #24
32; CHECK-NEXT:	orr	x11, x11, x12, lsl #16
33; CHECK-NEXT:	orr	x0, x11, x10
34; CHECK-NEXT:	cbnz	x13, .LBB0_1
35; CHECK-NEXT:  // %bb.2: // %exit
36; CHECK-NEXT:    ret
37entry:
38  %var = load ptr, ptr @global, align 8
39  br label %preheader
40
41preheader:
42  br label %header
43
44header:                                              ; preds = %bb63, %bb
45  %var4 = phi i64 [ %var30, %latch ], [ 0, %preheader ]
46  %var5 = phi ptr [ %var38, %latch ], [ %var, %preheader ]
47  %var6 = phi i8 [ %var21, %latch ], [ 0, %preheader ]
48  br label %midblock
49
50midblock:                                             ; preds = %bb9
51  %var15 = getelementptr inbounds %struct.wobble, ptr %var5, i64 9
52  %var17 = load i16, ptr %var15, align 8
53  %var18 = icmp eq i16 %var17, 0
54  %var19 = lshr i16 %var17, 8
55  %var20 = trunc i16 %var19 to i8
56  %var21 = select i1 %var18, i8 %var6, i8 %var20
57  %var22 = zext i8 %var21 to i16
58  %var23 = shl nuw i16 %var22, 8
59  %var24 = and i16 %var17, 255
60  %var25 = or i16 %var23, %var24
61  %var26 = select i1 %var18, i64 0, i64 65536
62  %var27 = zext i16 %var25 to i64
63  %var28 = and i64 %var4, -4294967296
64  %var29 = or i64 %var26, %var28
65  %var30 = or i64 %var29, %var27
66  br label %latch
67
68latch:                                             ; preds = %bb14, %bb9
69  %var34 = getelementptr inbounds %struct.wobble, ptr %var5, i64 1, i32 0
70  %var35 = load ptr, ptr %var34, align 8
71  %var36 = icmp eq ptr %var35, null
72  %var37 = getelementptr inbounds %struct.zot, ptr %var35, i64 0, i32 2
73  %var38 = load ptr, ptr %var37, align 8
74  br i1 %var36, label %exit, label %header
75
76exit:
77  ret i64 %var30
78}
79
80define i64 @bfis_in_loop_undef() {
81; CHECK-LABEL: bfis_in_loop_undef:
82; CHECK:       // %bb.0: // %entry
83; CHECK-NEXT: 	adrp	x9, :got:global
84; CHECK-NEXT: 	mov	w8, wzr
85; CHECK-NEXT:                                         // implicit-def: $x0
86; CHECK-NEXT: 	ldr	x9, [x9, :got_lo12:global]
87; CHECK-NEXT: 	ldr	x9, [x9]
88; CHECK-NEXT: .LBB1_1:                                // %midblock
89; CHECK-NEXT:                                         // =>This Inner Loop Header: Depth=1
90; CHECK-NEXT:	ldrh	w10, [x9, #72]
91; CHECK-NEXT:	ldr	x13, [x9, #8]
92; CHECK-NEXT:	lsr	w11, w10, #8
93; CHECK-NEXT:	cmp	w10, #0
94; CHECK-NEXT:	ldr	x9, [x13, #16]
95; CHECK-NEXT:	cset	w12, ne
96; CHECK-NEXT:	csel	w8, w8, w11, eq
97; CHECK-NEXT:	and	x11, x0, #0xffffffff00000000
98; CHECK-NEXT:	bfi	w10, w8, #8, #24
99; CHECK-NEXT:	orr	x11, x11, x12, lsl #16
100; CHECK-NEXT:	orr	x0, x11, x10
101; CHECK-NEXT:	cbnz	x13, .LBB1_1
102; CHECK-NEXT:  // %bb.2: // %exit
103; CHECK-NEXT:    ret
104entry:
105  %var = load ptr, ptr @global, align 8
106  br label %preheader
107
108preheader:
109  br label %header
110
111header:                                              ; preds = %bb63, %bb
112  %var4 = phi i64 [ %var30, %latch ], [ undef, %preheader ]
113  %var5 = phi ptr [ %var38, %latch ], [ %var, %preheader ]
114  %var6 = phi i8 [ %var21, %latch ], [ undef, %preheader ]
115  br label %midblock
116
117midblock:                                             ; preds = %bb9
118  %var15 = getelementptr inbounds %struct.wobble, ptr %var5, i64 9
119  %var17 = load i16, ptr %var15, align 8
120  %var18 = icmp eq i16 %var17, 0
121  %var19 = lshr i16 %var17, 8
122  %var20 = trunc i16 %var19 to i8
123  %var21 = select i1 %var18, i8 %var6, i8 %var20
124  %var22 = zext i8 %var21 to i16
125  %var23 = shl nuw i16 %var22, 8
126  %var24 = and i16 %var17, 255
127  %var25 = or i16 %var23, %var24
128  %var26 = select i1 %var18, i64 0, i64 65536
129  %var27 = zext i16 %var25 to i64
130  %var28 = and i64 %var4, -4294967296
131  %var29 = or i64 %var26, %var28
132  %var30 = or i64 %var29, %var27
133  br label %latch
134
135latch:                                             ; preds = %bb14, %bb9
136  %var34 = getelementptr inbounds %struct.wobble, ptr %var5, i64 1, i32 0
137  %var35 = load ptr, ptr %var34, align 8
138  %var36 = icmp eq ptr %var35, null
139  %var37 = getelementptr inbounds %struct.zot, ptr %var35, i64 0, i32 2
140  %var38 = load ptr, ptr %var37, align 8
141  br i1 %var36, label %exit, label %header
142
143exit:
144  ret i64 %var30
145}
146