1; RUN: llc < %s -mcpu=cortex-a15 -verify-machineinstrs -arm-atomic-cfg-tidy=0 | FileCheck %s 2 3; Check a spill right after a function call with large struct byval is correctly 4; generated. 5; PR16393 6 7; We expect the spill to be generated in %if.end230 and the reloads in 8; %if.end249 and %for.body285. 9 10; CHECK: set_stored_macroblock_parameters 11; CHECK: @ %if.end230 12; CHECK-NOT:@ %if. 13; CHECK-NOT:@ %for. 14; CHECK: str r{{.*}}, [sp, [[SLOT:#[0-9]+]]] @ 4-byte Spill 15; CHECK: @ %if.end249 16; CHECK-NOT:@ %if. 17; CHECK-NOT:@ %for. 18; CHECK: ldr r{{.*}}, [sp, [[SLOT]]] @ 4-byte Reload 19; CHECK: @ %for.body285 20; CHECK-NOT:@ %if. 21; CHECK-NOT:@ %for. 22; CHECK: ldr r{{.*}}, [sp, [[SLOT]]] @ 4-byte Reload 23 24target triple = "armv7l-unknown-linux-gnueabihf" 25 26%structA = type { double, [16 x [16 x i16]], [16 x [16 x i16]], [16 x [16 x i16]], i32****, i32***, i32, i16, [4 x i32], [4 x i32], i8**, [16 x i8], [16 x i8], i32, i64, i32, i16******, i16******, [2 x [4 x [4 x i8]]], i32, i32, i32, i32, i32, i32, i32, i32, i32 } 27%structB = type { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, float, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i8**, i8**, i32, i32***, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, [9 x [16 x [16 x i16]]], [5 x [16 x [16 x i16]]], [9 x [8 x [8 x i16]]], [2 x [4 x [16 x [16 x i16]]]], [16 x [16 x i16]], [16 x [16 x i32]], i32****, i32***, i32***, i32***, i32****, i32****, %structC*, %structD*, %structK*, i32*, i32*, i32, i32, i32, i32, [4 x [4 x i32]], i32, i32, i32, i32, i32, double, i32, i32, i32, i32, i16******, i16******, i16******, i16******, [15 x i16], i32, i32, i32, i32, i32, i32, i32, i32, [6 x [32 x i32]], i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, [1 x i32], i32, i32, [2 x i32], i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, %structL*, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, double**, double***, i32***, double**, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, [3 x [2 x i32]], [2 x i32], i32, i32, i16, i32, i32, i32, i32, i32 } 28%structC = type { i32, i32, [100 x %structD*], i32, float, float, float } 29%structD = type { i32, i32, i32, i32, i32, i32, %structE*, %structH*, %structJ*, i32, i32*, i32*, i32*, i32, i32*, i32*, i32*, i32 (i32)*, [3 x [2 x i32]] } 30%structE = type { %structF*, %structG, %structG } 31%structF = type { i32, i32, i8, i32, i32, i8, i8, i32, i32, i8*, i32 } 32%structG = type { i32, i32, i32, i32, i32, i8*, i32*, i32, i32 } 33%structH = type { [3 x [11 x %structI]], [2 x [9 x %structI]], [2 x [10 x %structI]], [2 x [6 x %structI]], [4 x %structI], [4 x %structI], [3 x %structI] } 34%structI = type { i16, i8, i32 } 35%structJ = type { [2 x %structI], [4 x %structI], [3 x [4 x %structI]], [10 x [4 x %structI]], [10 x [15 x %structI]], [10 x [15 x %structI]], [10 x [5 x %structI]], [10 x [5 x %structI]], [10 x [15 x %structI]], [10 x [15 x %structI]] } 36%structK = type { i32, i32, i32, [2 x i32], i32, [8 x i32], %structK*, %structK*, i32, [2 x [4 x [4 x [2 x i32]]]], [16 x i8], [16 x i8], i32, i64, [4 x i32], [4 x i32], i64, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i16, double, i32, i32, i32, i32, i32, i32, i32, i32, i32 } 37%structL = type { i32, i32, i32, i32, i32, %structL* } 38%structM = type { i32, i32, i32, i32, i32, i32, [6 x [33 x i64]], [6 x [33 x i64]], [6 x [33 x i64]], [6 x [33 x i64]], i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i16**, i16****, i16****, i16*****, i16***, i8*, i8***, i64***, i64***, i16****, i8**, i8**, %structM*, %structM*, %structM*, i32, i32, i32, i32, i32, i32, i32 } 39%structN = type { i32, [16 x [16 x i32]], [16 x [16 x i32]], [16 x [16 x i32]], [3 x [16 x [16 x i32]]], [4 x i16], [4 x i8], [4 x i8], [4 x i8], [16 x [16 x i16]], [16 x [16 x i16]], [16 x [16 x i32]] } 40 41@cofAC = external global i32****, align 4 42@cofDC = external global i32***, align 4 43@rdopt = external global %structA*, align 4 44@img = external global %structB* 45@enc_picture = external global %structM* 46@si_frame_indicator = external global i32, align 4 47@sp2_frame_indicator = external global i32, align 4 48@lrec = external global i32**, align 4 49@tr8x8 = external global %structN, align 4 50@best_mode = external global i16, align 2 51@best_c_imode = external global i32, align 4 52@best_i16offset = external global i32, align 4 53@bi_pred_me = external global i16, align 2 54@b8mode = external global [4 x i32], align 4 55@b8pdir = external global [4 x i32], align 4 56@b4_intra_pred_modes = external global [16 x i8], align 1 57@b8_intra_pred_modes8x8 = external global [16 x i8], align 1 58@b4_ipredmode = external global [16 x i8], align 1 59@b8_ipredmode8x8 = external global [4 x [4 x i8]], align 1 60@rec_mbY = external global [16 x [16 x i16]], align 2 61@lrec_rec = external global [16 x [16 x i32]], align 4 62@rec_mbU = external global [16 x [16 x i16]], align 2 63@rec_mbV = external global [16 x [16 x i16]], align 2 64@lrec_rec_U = external global [16 x [16 x i32]], align 4 65@lrec_uv = external global i32***, align 4 66@lrec_rec_V = external global [16 x [16 x i32]], align 4 67@cbp = external global i32, align 4 68@cbp_blk = external global i64, align 8 69@luma_transform_size_8x8_flag = external global i32, align 4 70@frefframe = external global [4 x [4 x i8]], align 1 71@brefframe = external global [4 x [4 x i8]], align 1 72 73; Function Attrs: nounwind 74declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) #0 75 76; Function Attrs: nounwind 77declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) #0 78 79; Function Attrs: nounwind 80declare void @SetMotionVectorsMB(%structK* nocapture, i32) #1 81 82; Function Attrs: nounwind 83define void @set_stored_macroblock_parameters() #1 { 84entry: 85 %0 = load %structB*, %structB** @img, align 4 86 %1 = load i32, i32* undef, align 4 87 %mb_data = getelementptr inbounds %structB, %structB* %0, i32 0, i32 61 88 %2 = load %structK*, %structK** %mb_data, align 4 89 br label %for.body 90 91for.body: ; preds = %for.body, %entry 92 br i1 undef, label %for.end, label %for.body 93 94for.end: ; preds = %for.body 95 br i1 undef, label %for.body20, label %if.end 96 97for.body20: ; preds = %for.end 98 unreachable 99 100if.end: ; preds = %for.end 101 br i1 undef, label %if.end40, label %for.cond31.preheader 102 103for.cond31.preheader: ; preds = %if.end 104 unreachable 105 106if.end40: ; preds = %if.end 107 br i1 undef, label %if.end43, label %if.then42 108 109if.then42: ; preds = %if.end40 110 br label %if.end43 111 112if.end43: ; preds = %if.then42, %if.end40 113 br i1 undef, label %if.end164, label %for.cond47.preheader 114 115for.cond47.preheader: ; preds = %if.end43 116 br i1 undef, label %for.body119, label %if.end164 117 118for.body119: ; preds = %for.body119, %for.cond47.preheader 119 br i1 undef, label %for.body119, label %if.end164 120 121if.end164: ; preds = %for.body119, %for.cond47.preheader, %if.end43 122 store i32*** null, i32**** @cofDC, align 4 123 %mb_type = getelementptr inbounds %structK, %structK* %2, i32 %1, i32 8 124 br i1 undef, label %if.end230, label %if.then169 125 126if.then169: ; preds = %if.end164 127 br i1 undef, label %for.cond185.preheader, label %for.cond210.preheader 128 129for.cond185.preheader: ; preds = %if.then169 130 unreachable 131 132for.cond210.preheader: ; preds = %if.then169 133 unreachable 134 135if.end230: ; preds = %if.end164 136 tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* undef, i8* bitcast ([4 x i32]* @b8mode to i8*), i32 16, i32 4, i1 false) 137 %b8pdir = getelementptr inbounds %structK, %structK* %2, i32 %1, i32 15 138 %3 = bitcast [4 x i32]* %b8pdir to i8* 139 tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %3, i8* bitcast ([4 x i32]* @b8pdir to i8*), i32 16, i32 4, i1 false) 140 br i1 undef, label %if.end236, label %if.then233 141 142if.then233: ; preds = %if.end230 143 unreachable 144 145if.end236: ; preds = %if.end230 146 %cmp242 = icmp ne i16 undef, 8 147 %4 = load i32, i32* @luma_transform_size_8x8_flag, align 4 148 %tobool245 = icmp ne i32 %4, 0 149 %or.cond812 = or i1 %cmp242, %tobool245 150 br i1 %or.cond812, label %if.end249, label %land.lhs.true246 151 152land.lhs.true246: ; preds = %if.end236 153 br i1 undef, label %if.end249, label %if.then248 154 155if.then248: ; preds = %land.lhs.true246 156 tail call void asm sideeffect "", "~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11}"() nounwind 157 tail call void @RestoreMVBlock8x8(i32 1, i32 0, %structN* byval @tr8x8, i32 0) #0 158 tail call void @RestoreMVBlock8x8(i32 1, i32 2, %structN* byval @tr8x8, i32 0) #0 159 tail call void @RestoreMVBlock8x8(i32 1, i32 3, %structN* byval @tr8x8, i32 0) #0 160 br label %if.end249 161 162if.end249: ; preds = %if.then248, %land.lhs.true246, %if.end236 163 %5 = load i32, i32* @luma_transform_size_8x8_flag, align 4 164 %6 = load %structA*, %structA** @rdopt, align 4 165 %luma_transform_size_8x8_flag264 = getelementptr inbounds %structA, %structA* %6, i32 0, i32 21 166 store i32 %5, i32* %luma_transform_size_8x8_flag264, align 4 167 %7 = load i32, i32* undef, align 4 168 %add281 = add nsw i32 %7, 0 169 br label %for.body285 170 171for.body285: ; preds = %for.inc503, %if.end249 172 %8 = phi %structB* [ undef, %if.end249 ], [ %.pre1155, %for.inc503 ] 173 %i.21103 = phi i32 [ 0, %if.end249 ], [ %inc504, %for.inc503 ] 174 %block_x286 = getelementptr inbounds %structB, %structB* %8, i32 0, i32 37 175 %9 = load i32, i32* %block_x286, align 4 176 %add287 = add nsw i32 %9, %i.21103 177 %shr289 = ashr i32 %i.21103, 1 178 %add290 = add nsw i32 %shr289, 0 179 %arrayidx292 = getelementptr inbounds %structK, %structK* %2, i32 %1, i32 15, i32 %add290 180 %10 = load %structM*, %structM** @enc_picture, align 4 181 %ref_idx = getelementptr inbounds %structM, %structM* %10, i32 0, i32 35 182 %11 = load i8***, i8**** %ref_idx, align 4 183 %12 = load i8**, i8*** %11, align 4 184 %arrayidx313 = getelementptr inbounds i8*, i8** %12, i32 %add281 185 %13 = load i8*, i8** %arrayidx313, align 4 186 %arrayidx314 = getelementptr inbounds i8, i8* %13, i32 %add287 187 store i8 -1, i8* %arrayidx314, align 1 188 %14 = load %structB*, %structB** @img, align 4 189 %MbaffFrameFlag327 = getelementptr inbounds %structB, %structB* %14, i32 0, i32 100 190 %15 = load i32, i32* %MbaffFrameFlag327, align 4 191 %tobool328 = icmp eq i32 %15, 0 192 br i1 %tobool328, label %if.end454, label %if.then329 193 194if.then329: ; preds = %for.body285 195 %16 = load %structA*, %structA** @rdopt, align 4 196 br label %if.end454 197 198if.end454: ; preds = %if.then329, %for.body285 199 %17 = load i32, i32* %arrayidx292, align 4 200 %cmp457 = icmp eq i32 %17, 0 201 br i1 %cmp457, label %if.then475, label %lor.lhs.false459 202 203lor.lhs.false459: ; preds = %if.end454 204 %18 = load i32, i32* %mb_type, align 4 205 switch i32 %18, label %for.inc503 [ 206 i32 9, label %if.then475 207 i32 11, label %if.then475 208 i32 13, label %if.then475 209 i32 14, label %if.then475 210 ] 211 212if.then475: ; preds = %lor.lhs.false459, %lor.lhs.false459, %lor.lhs.false459, %lor.lhs.false459, %if.end454 213 store i16 0, i16* undef, align 2 214 br label %for.inc503 215 216for.inc503: ; preds = %if.then475, %lor.lhs.false459 217 %inc504 = add nsw i32 %i.21103, 1 218 %.pre1155 = load %structB*, %structB** @img, align 4 219 br label %for.body285 220} 221 222; Function Attrs: nounwind 223declare void @update_offset_params(i32, i32) #1 224 225; Function Attrs: nounwind 226declare void @RestoreMVBlock8x8(i32, i32, %structN* byval nocapture, i32) #1 227 228attributes #0 = { nounwind } 229attributes #1 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } 230