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
; RUN: opt -mtriple=aarch64-linux-gnu -passes=typepromotion < %s | llc -mtriple=aarch64-linux-gnu -o - | FileCheck %s
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
%struct.bar = type { %struct.foo }
%struct.foo = type { ptr }
%struct.wobble = type { ptr }
%struct.zot = type <{ %struct.wobble, ptr, ptr, i8, [7 x i8] }>
@global = external global %struct.bar, align 8
define i64 @bfis_in_loop_zero() {
; CHECK-LABEL: bfis_in_loop_zero:
; CHECK:       // %bb.0: // %entry
; CHECK-NEXT: 	adrp	x8, :got:global
; CHECK-NEXT: 	mov	x0, xzr
; CHECK-NEXT: 	mov	w9, wzr
; CHECK-NEXT: 	ldr	x8, [x8, :got_lo12:global]
; CHECK-NEXT: 	ldr	x8, [x8]
; CHECK-NEXT: .LBB0_1:                                // %midblock
; CHECK-NEXT:   // =>This Inner Loop Header: Depth=1
; CHECK-NEXT:	ldrh	w10, [x8, #72]
; CHECK-NEXT:	ldr	x13, [x8, #8]
; CHECK-NEXT:	lsr	w11, w10, #8
; CHECK-NEXT:	cmp	w10, #0
; CHECK-NEXT:	ldr	x8, [x13, #16]
; CHECK-NEXT:	cset	w12, ne
; CHECK-NEXT:	csel	w9, w9, w11, eq
; CHECK-NEXT:	and	x11, x0, #0xffffffff00000000
; CHECK-NEXT:	bfi	w10, w9, #8, #24
; CHECK-NEXT:	orr	x11, x11, x12, lsl #16
; CHECK-NEXT:	orr	x0, x11, x10
; CHECK-NEXT:	cbnz	x13, .LBB0_1
; CHECK-NEXT:  // %bb.2: // %exit
; CHECK-NEXT:    ret
entry:
  %var = load ptr, ptr @global, align 8
  br label %preheader
preheader:
  br label %header
header:                                              ; preds = %bb63, %bb
  %var4 = phi i64 [ %var30, %latch ], [ 0, %preheader ]
  %var5 = phi ptr [ %var38, %latch ], [ %var, %preheader ]
  %var6 = phi i8 [ %var21, %latch ], [ 0, %preheader ]
  br label %midblock
midblock:                                             ; preds = %bb9
  %var15 = getelementptr inbounds %struct.wobble, ptr %var5, i64 9
  %var17 = load i16, ptr %var15, align 8
  %var18 = icmp eq i16 %var17, 0
  %var19 = lshr i16 %var17, 8
  %var20 = trunc i16 %var19 to i8
  %var21 = select i1 %var18, i8 %var6, i8 %var20
  %var22 = zext i8 %var21 to i16
  %var23 = shl nuw i16 %var22, 8
  %var24 = and i16 %var17, 255
  %var25 = or i16 %var23, %var24
  %var26 = select i1 %var18, i64 0, i64 65536
  %var27 = zext i16 %var25 to i64
  %var28 = and i64 %var4, -4294967296
  %var29 = or i64 %var26, %var28
  %var30 = or i64 %var29, %var27
  br label %latch
latch:                                             ; preds = %bb14, %bb9
  %var34 = getelementptr inbounds %struct.wobble, ptr %var5, i64 1, i32 0
  %var35 = load ptr, ptr %var34, align 8
  %var36 = icmp eq ptr %var35, null
  %var37 = getelementptr inbounds %struct.zot, ptr %var35, i64 0, i32 2
  %var38 = load ptr, ptr %var37, align 8
  br i1 %var36, label %exit, label %header
exit:
  ret i64 %var30
}
define i64 @bfis_in_loop_undef() {
; CHECK-LABEL: bfis_in_loop_undef:
; CHECK:       // %bb.0: // %entry
; CHECK-NEXT: 	adrp	x9, :got:global
; CHECK-NEXT: 	mov	w8, wzr
; CHECK-NEXT:                                         // implicit-def: $x0
; CHECK-NEXT: 	ldr	x9, [x9, :got_lo12:global]
; CHECK-NEXT: 	ldr	x9, [x9]
; CHECK-NEXT: .LBB1_1:                                // %midblock
; CHECK-NEXT:                                         // =>This Inner Loop Header: Depth=1
; CHECK-NEXT:	ldrh	w10, [x9, #72]
; CHECK-NEXT:	ldr	x13, [x9, #8]
; CHECK-NEXT:	lsr	w11, w10, #8
; CHECK-NEXT:	cmp	w10, #0
; CHECK-NEXT:	ldr	x9, [x13, #16]
; CHECK-NEXT:	cset	w12, ne
; CHECK-NEXT:	csel	w8, w8, w11, eq
; CHECK-NEXT:	and	x11, x0, #0xffffffff00000000
; CHECK-NEXT:	bfi	w10, w8, #8, #24
; CHECK-NEXT:	orr	x11, x11, x12, lsl #16
; CHECK-NEXT:	orr	x0, x11, x10
; CHECK-NEXT:	cbnz	x13, .LBB1_1
; CHECK-NEXT:  // %bb.2: // %exit
; CHECK-NEXT:    ret
entry:
  %var = load ptr, ptr @global, align 8
  br label %preheader
preheader:
  br label %header
header:                                              ; preds = %bb63, %bb
  %var4 = phi i64 [ %var30, %latch ], [ undef, %preheader ]
  %var5 = phi ptr [ %var38, %latch ], [ %var, %preheader ]
  %var6 = phi i8 [ %var21, %latch ], [ undef, %preheader ]
  br label %midblock
midblock:                                             ; preds = %bb9
  %var15 = getelementptr inbounds %struct.wobble, ptr %var5, i64 9
  %var17 = load i16, ptr %var15, align 8
  %var18 = icmp eq i16 %var17, 0
  %var19 = lshr i16 %var17, 8
  %var20 = trunc i16 %var19 to i8
  %var21 = select i1 %var18, i8 %var6, i8 %var20
  %var22 = zext i8 %var21 to i16
  %var23 = shl nuw i16 %var22, 8
  %var24 = and i16 %var17, 255
  %var25 = or i16 %var23, %var24
  %var26 = select i1 %var18, i64 0, i64 65536
  %var27 = zext i16 %var25 to i64
  %var28 = and i64 %var4, -4294967296
  %var29 = or i64 %var26, %var28
  %var30 = or i64 %var29, %var27
  br label %latch
latch:                                             ; preds = %bb14, %bb9
  %var34 = getelementptr inbounds %struct.wobble, ptr %var5, i64 1, i32 0
  %var35 = load ptr, ptr %var34, align 8
  %var36 = icmp eq ptr %var35, null
  %var37 = getelementptr inbounds %struct.zot, ptr %var35, i64 0, i32 2
  %var38 = load ptr, ptr %var37, align 8
  br i1 %var36, label %exit, label %header
exit:
  ret i64 %var30
}
 
     |