1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4target datalayout = "n32:64" 5 6define void @MainKernel(i32 %iNumSteps, i32 %tid, i32 %base) { 7; CHECK-LABEL: @MainKernel( 8; CHECK-NEXT: [[CALLA:%.*]] = alloca [258 x float], align 4 9; CHECK-NEXT: [[CALLB:%.*]] = alloca [258 x float], align 4 10; CHECK-NEXT: [[CONV_I:%.*]] = uitofp i32 [[INUMSTEPS:%.*]] to float 11; CHECK-NEXT: [[CONV_I12:%.*]] = zext i32 [[TID:%.*]] to i64 12; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds nuw [258 x float], ptr [[CALLA]], i64 0, i64 [[CONV_I12]] 13; CHECK-NEXT: store float [[CONV_I]], ptr [[ARRAYIDX3]], align 4 14; CHECK-NEXT: [[ARRAYIDX6:%.*]] = getelementptr inbounds nuw [258 x float], ptr [[CALLB]], i64 0, i64 [[CONV_I12]] 15; CHECK-NEXT: store float [[CONV_I]], ptr [[ARRAYIDX6]], align 4 16; CHECK-NEXT: [[CMP7:%.*]] = icmp eq i32 [[TID]], 0 17; CHECK-NEXT: br i1 [[CMP7]], label [[DOTBB1:%.*]], label [[DOTBB2:%.*]] 18; CHECK: .bb1: 19; CHECK-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw i8, ptr [[CALLA]], i64 1024 20; CHECK-NEXT: store float [[CONV_I]], ptr [[ARRAYIDX10]], align 4 21; CHECK-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds nuw i8, ptr [[CALLB]], i64 1024 22; CHECK-NEXT: store float 0.000000e+00, ptr [[ARRAYIDX11]], align 4 23; CHECK-NEXT: br label [[DOTBB2]] 24; CHECK: .bb2: 25; CHECK-NEXT: [[CMP135:%.*]] = icmp sgt i32 [[INUMSTEPS]], 0 26; CHECK-NEXT: br i1 [[CMP135]], label [[DOTBB3:%.*]], label [[DOTBB8:%.*]] 27; CHECK: .bb3: 28; CHECK-NEXT: [[TMP1:%.*]] = phi float [ [[TMP10:%.*]], [[DOTBB12:%.*]] ], [ [[CONV_I]], [[DOTBB2]] ] 29; CHECK-NEXT: [[TMP2:%.*]] = phi float [ [[TMP11:%.*]], [[DOTBB12]] ], [ [[CONV_I]], [[DOTBB2]] ] 30; CHECK-NEXT: [[I12_06:%.*]] = phi i32 [ [[SUB:%.*]], [[DOTBB12]] ], [ [[INUMSTEPS]], [[DOTBB2]] ] 31; CHECK-NEXT: [[TMP3:%.*]] = icmp ugt i32 [[I12_06]], [[BASE:%.*]] 32; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 [[I12_06]], 1 33; CHECK-NEXT: [[CONV_I9:%.*]] = sext i32 [[ADD]] to i64 34; CHECK-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds [258 x float], ptr [[CALLA]], i64 0, i64 [[CONV_I9]] 35; CHECK-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds [258 x float], ptr [[CALLB]], i64 0, i64 [[CONV_I9]] 36; CHECK-NEXT: [[CMP40:%.*]] = icmp ult i32 [[I12_06]], [[BASE]] 37; CHECK-NEXT: br i1 [[TMP3]], label [[DOTBB4:%.*]], label [[DOTBB5:%.*]] 38; CHECK: .bb4: 39; CHECK-NEXT: [[TMP4:%.*]] = load float, ptr [[ARRAYIDX20]], align 4 40; CHECK-NEXT: [[TMP5:%.*]] = load float, ptr [[ARRAYIDX24]], align 4 41; CHECK-NEXT: [[ADD33:%.*]] = fadd float [[TMP5]], [[TMP4]] 42; CHECK-NEXT: [[ADD33_1:%.*]] = fadd float [[ADD33]], [[TMP1]] 43; CHECK-NEXT: [[ADD33_2:%.*]] = fadd float [[ADD33_1]], [[TMP2]] 44; CHECK-NEXT: br label [[DOTBB5]] 45; CHECK: .bb5: 46; CHECK-NEXT: [[TMP6:%.*]] = phi float [ [[ADD33_1]], [[DOTBB4]] ], [ [[TMP1]], [[DOTBB3]] ] 47; CHECK-NEXT: [[TMP7:%.*]] = phi float [ [[ADD33_2]], [[DOTBB4]] ], [ [[TMP2]], [[DOTBB3]] ] 48; CHECK-NEXT: br i1 [[CMP40]], label [[DOTBB6:%.*]], label [[DOTBB7:%.*]] 49; CHECK: .bb6: 50; CHECK-NEXT: store float [[TMP7]], ptr [[ARRAYIDX3]], align 4 51; CHECK-NEXT: store float [[TMP6]], ptr [[ARRAYIDX6]], align 4 52; CHECK-NEXT: br label [[DOTBB7]] 53; CHECK: .bb7: 54; CHECK-NEXT: br i1 [[TMP3]], label [[DOTBB9:%.*]], label [[DOTBB10:%.*]] 55; CHECK: .bb8: 56; CHECK-NEXT: ret void 57; CHECK: .bb9: 58; CHECK-NEXT: [[TMP8:%.*]] = load float, ptr [[ARRAYIDX20]], align 4 59; CHECK-NEXT: [[TMP9:%.*]] = load float, ptr [[ARRAYIDX24]], align 4 60; CHECK-NEXT: [[ADD33_112:%.*]] = fadd float [[TMP9]], [[TMP8]] 61; CHECK-NEXT: [[ADD33_1_1:%.*]] = fadd float [[ADD33_112]], [[TMP6]] 62; CHECK-NEXT: [[ADD33_2_1:%.*]] = fadd float [[ADD33_1_1]], [[TMP7]] 63; CHECK-NEXT: br label [[DOTBB10]] 64; CHECK: .bb10: 65; CHECK-NEXT: [[TMP10]] = phi float [ [[ADD33_1_1]], [[DOTBB9]] ], [ [[TMP6]], [[DOTBB7]] ] 66; CHECK-NEXT: [[TMP11]] = phi float [ [[ADD33_2_1]], [[DOTBB9]] ], [ [[TMP7]], [[DOTBB7]] ] 67; CHECK-NEXT: br i1 [[CMP40]], label [[DOTBB11:%.*]], label [[DOTBB12]] 68; CHECK: .bb11: 69; CHECK-NEXT: store float [[TMP11]], ptr [[ARRAYIDX3]], align 4 70; CHECK-NEXT: store float [[TMP10]], ptr [[ARRAYIDX6]], align 4 71; CHECK-NEXT: br label [[DOTBB12]] 72; CHECK: .bb12: 73; CHECK-NEXT: [[SUB]] = add nsw i32 [[I12_06]], -4 74; CHECK-NEXT: [[CMP13:%.*]] = icmp sgt i32 [[I12_06]], 4 75; CHECK-NEXT: br i1 [[CMP13]], label [[DOTBB3]], label [[DOTBB8]] 76; 77 %callA = alloca [258 x float], align 4 78 %callB = alloca [258 x float], align 4 79 %conv.i = uitofp i32 %iNumSteps to float 80 %1 = bitcast float %conv.i to i32 81 %conv.i12 = zext i32 %tid to i64 82 %arrayidx3 = getelementptr inbounds [258 x float], ptr %callA, i64 0, i64 %conv.i12 83 store i32 %1, ptr %arrayidx3, align 4 84 %arrayidx6 = getelementptr inbounds [258 x float], ptr %callB, i64 0, i64 %conv.i12 85 store i32 %1, ptr %arrayidx6, align 4 86 %cmp7 = icmp eq i32 %tid, 0 87 br i1 %cmp7, label %.bb1, label %.bb2 88 89.bb1: 90 %arrayidx10 = getelementptr inbounds [258 x float], ptr %callA, i64 0, i64 256 91 store float %conv.i, ptr %arrayidx10, align 4 92 %arrayidx11 = getelementptr inbounds [258 x float], ptr %callB, i64 0, i64 256 93 store float 0.000000e+00, ptr %arrayidx11, align 4 94 br label %.bb2 95 96.bb2: 97 %cmp135 = icmp sgt i32 %iNumSteps, 0 98 br i1 %cmp135, label %.bb3, label %.bb8 99 100.bb3: 101 %rA.sroa.8.0 = phi i32 [ %rA.sroa.8.2, %.bb12 ], [ %1, %.bb2 ] 102 %rA.sroa.0.0 = phi i32 [ %rA.sroa.0.2, %.bb12 ], [ %1, %.bb2 ] 103 %i12.06 = phi i32 [ %sub, %.bb12 ], [ %iNumSteps, %.bb2 ] 104 %2 = icmp ugt i32 %i12.06, %base 105 %add = add i32 %i12.06, 1 106 %conv.i9 = sext i32 %add to i64 107 %arrayidx20 = getelementptr inbounds [258 x float], ptr %callA, i64 0, i64 %conv.i9 108 %arrayidx24 = getelementptr inbounds [258 x float], ptr %callB, i64 0, i64 %conv.i9 109 %cmp40 = icmp ult i32 %i12.06, %base 110 br i1 %2, label %.bb4, label %.bb5 111 112.bb4: 113 %3 = load i32, ptr %arrayidx20, align 4 114 %4 = load i32, ptr %arrayidx24, align 4 115 %5 = bitcast i32 %4 to float 116 %6 = bitcast i32 %3 to float 117 %add33 = fadd float %5, %6 118 %7 = bitcast i32 %rA.sroa.8.0 to float 119 %add33.1 = fadd float %add33, %7 120 %8 = bitcast float %add33.1 to i32 121 %9 = bitcast i32 %rA.sroa.0.0 to float 122 %add33.2 = fadd float %add33.1, %9 123 %10 = bitcast float %add33.2 to i32 124 br label %.bb5 125 126.bb5: 127 %rA.sroa.8.1 = phi i32 [ %8, %.bb4 ], [ %rA.sroa.8.0, %.bb3 ] 128 %rA.sroa.0.1 = phi i32 [ %10, %.bb4 ], [ %rA.sroa.0.0, %.bb3 ] 129 br i1 %cmp40, label %.bb6, label %.bb7 130 131.bb6: 132 store i32 %rA.sroa.0.1, ptr %arrayidx3, align 4 133 store i32 %rA.sroa.8.1, ptr %arrayidx6, align 4 134 br label %.bb7 135 136.bb7: 137 br i1 %2, label %.bb9, label %.bb10 138 139.bb8: 140 ret void 141 142.bb9: 143 %11 = load i32, ptr %arrayidx20, align 4 144 %12 = load i32, ptr %arrayidx24, align 4 145 %13 = bitcast i32 %12 to float 146 %14 = bitcast i32 %11 to float 147 %add33.112 = fadd float %13, %14 148 %15 = bitcast i32 %rA.sroa.8.1 to float 149 %add33.1.1 = fadd float %add33.112, %15 150 %16 = bitcast float %add33.1.1 to i32 151 %17 = bitcast i32 %rA.sroa.0.1 to float 152 %add33.2.1 = fadd float %add33.1.1, %17 153 %18 = bitcast float %add33.2.1 to i32 154 br label %.bb10 155 156.bb10: 157 %rA.sroa.8.2 = phi i32 [ %16, %.bb9 ], [ %rA.sroa.8.1, %.bb7 ] 158 %rA.sroa.0.2 = phi i32 [ %18, %.bb9 ], [ %rA.sroa.0.1, %.bb7 ] 159 br i1 %cmp40, label %.bb11, label %.bb12 160 161.bb11: 162 store i32 %rA.sroa.0.2, ptr %arrayidx3, align 4 163 store i32 %rA.sroa.8.2, ptr %arrayidx6, align 4 164 br label %.bb12 165 166.bb12: 167 %sub = add i32 %i12.06, -4 168 %cmp13 = icmp sgt i32 %sub, 0 169 br i1 %cmp13, label %.bb3, label %.bb8 170} 171 172declare i32 @get_i32() 173declare i3 @get_i3() 174declare void @bar() 175 176define i37 @zext_from_legal_to_illegal_type(i32 %x) { 177; CHECK-LABEL: @zext_from_legal_to_illegal_type( 178; CHECK-NEXT: entry: 179; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 42 180; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] 181; CHECK: t: 182; CHECK-NEXT: [[Y:%.*]] = call i32 @get_i32() 183; CHECK-NEXT: br label [[EXIT:%.*]] 184; CHECK: f: 185; CHECK-NEXT: call void @bar() 186; CHECK-NEXT: br label [[EXIT]] 187; CHECK: exit: 188; CHECK-NEXT: [[P:%.*]] = phi i32 [ [[Y]], [[T]] ], [ 3, [[F]] ] 189; CHECK-NEXT: [[R:%.*]] = zext i32 [[P]] to i37 190; CHECK-NEXT: ret i37 [[R]] 191; 192entry: 193 %cmp = icmp eq i32 %x, 42 194 br i1 %cmp, label %t, label %f 195 196t: 197 %y = call i32 @get_i32() 198 br label %exit 199 200f: 201 call void @bar() 202 br label %exit 203 204exit: 205 %p = phi i32 [ %y, %t ], [ 3, %f ] 206 %r = zext i32 %p to i37 207 ret i37 %r 208} 209 210define i37 @zext_from_illegal_to_illegal_type(i32 %x) { 211; CHECK-LABEL: @zext_from_illegal_to_illegal_type( 212; CHECK-NEXT: entry: 213; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 42 214; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] 215; CHECK: t: 216; CHECK-NEXT: [[Y:%.*]] = call i3 @get_i3() 217; CHECK-NEXT: br label [[EXIT:%.*]] 218; CHECK: f: 219; CHECK-NEXT: call void @bar() 220; CHECK-NEXT: br label [[EXIT]] 221; CHECK: exit: 222; CHECK-NEXT: [[P:%.*]] = phi i3 [ [[Y]], [[T]] ], [ 3, [[F]] ] 223; CHECK-NEXT: [[R:%.*]] = zext i3 [[P]] to i37 224; CHECK-NEXT: ret i37 [[R]] 225; 226entry: 227 %cmp = icmp eq i32 %x, 42 228 br i1 %cmp, label %t, label %f 229 230t: 231 %y = call i3 @get_i3() 232 br label %exit 233 234f: 235 call void @bar() 236 br label %exit 237 238exit: 239 %p = phi i3 [ %y, %t ], [ 3, %f ] 240 %r = zext i3 %p to i37 241 ret i37 %r 242} 243 244define i64 @zext_from_legal_to_legal_type(i32 %x) { 245; CHECK-LABEL: @zext_from_legal_to_legal_type( 246; CHECK-NEXT: entry: 247; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 42 248; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] 249; CHECK: t: 250; CHECK-NEXT: [[Y:%.*]] = call i32 @get_i32() 251; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[Y]] to i64 252; CHECK-NEXT: br label [[EXIT:%.*]] 253; CHECK: f: 254; CHECK-NEXT: call void @bar() 255; CHECK-NEXT: br label [[EXIT]] 256; CHECK: exit: 257; CHECK-NEXT: [[P:%.*]] = phi i64 [ [[TMP0]], [[T]] ], [ 3, [[F]] ] 258; CHECK-NEXT: ret i64 [[P]] 259; 260entry: 261 %cmp = icmp eq i32 %x, 42 262 br i1 %cmp, label %t, label %f 263 264t: 265 %y = call i32 @get_i32() 266 br label %exit 267 268f: 269 call void @bar() 270 br label %exit 271 272exit: 273 %p = phi i32 [ %y, %t ], [ 3, %f ] 274 %r = zext i32 %p to i64 275 ret i64 %r 276} 277 278define i64 @zext_from_illegal_to_legal_type(i32 %x) { 279; CHECK-LABEL: @zext_from_illegal_to_legal_type( 280; CHECK-NEXT: entry: 281; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 42 282; CHECK-NEXT: br i1 [[CMP]], label [[T:%.*]], label [[F:%.*]] 283; CHECK: t: 284; CHECK-NEXT: [[Y:%.*]] = call i3 @get_i3() 285; CHECK-NEXT: [[TMP0:%.*]] = zext i3 [[Y]] to i64 286; CHECK-NEXT: br label [[EXIT:%.*]] 287; CHECK: f: 288; CHECK-NEXT: call void @bar() 289; CHECK-NEXT: br label [[EXIT]] 290; CHECK: exit: 291; CHECK-NEXT: [[P:%.*]] = phi i64 [ [[TMP0]], [[T]] ], [ 3, [[F]] ] 292; CHECK-NEXT: ret i64 [[P]] 293; 294entry: 295 %cmp = icmp eq i32 %x, 42 296 br i1 %cmp, label %t, label %f 297 298t: 299 %y = call i3 @get_i3() 300 br label %exit 301 302f: 303 call void @bar() 304 br label %exit 305 306exit: 307 %p = phi i3 [ %y, %t ], [ 3, %f ] 308 %r = zext i3 %p to i64 309 ret i64 %r 310} 311 312define i8 @trunc_in_loop_exit_block() { 313; CHECK-LABEL: @trunc_in_loop_exit_block( 314; CHECK-NEXT: entry: 315; CHECK-NEXT: br label [[LOOP:%.*]] 316; CHECK: loop: 317; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 318; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ [[IV_NEXT]], [[LOOP_LATCH]] ] 319; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ult i32 [[IV]], 100 320; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_LATCH]], label [[EXIT:%.*]] 321; CHECK: loop.latch: 322; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 323; CHECK-NEXT: br label [[LOOP]] 324; CHECK: exit: 325; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 [[PHI]] to i8 326; CHECK-NEXT: ret i8 [[TRUNC]] 327; 328entry: 329 br label %loop 330 331loop: 332 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 333 %phi = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ] 334 %cmp = icmp ult i32 %iv, 100 335 br i1 %cmp, label %loop.latch, label %exit 336 337loop.latch: 338 %iv.next = add i32 %iv, 1 339 br label %loop 340 341exit: 342 %trunc = trunc i32 %phi to i8 343 ret i8 %trunc 344} 345 346define i32 @zext_in_loop_and_exit_block(i8 %step, i32 %end) { 347; CHECK-LABEL: @zext_in_loop_and_exit_block( 348; CHECK-NEXT: entry: 349; CHECK-NEXT: br label [[LOOP:%.*]] 350; CHECK: loop: 351; CHECK-NEXT: [[IV:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] 352; CHECK-NEXT: [[IV_EXT:%.*]] = zext i8 [[IV]] to i32 353; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[END:%.*]], [[IV_EXT]] 354; CHECK-NEXT: br i1 [[CMP_NOT]], label [[EXIT:%.*]], label [[LOOP_LATCH]] 355; CHECK: loop.latch: 356; CHECK-NEXT: [[IV_NEXT]] = add i8 [[IV]], [[STEP:%.*]] 357; CHECK-NEXT: br label [[LOOP]] 358; CHECK: exit: 359; CHECK-NEXT: [[EXT:%.*]] = zext i8 [[IV]] to i32 360; CHECK-NEXT: ret i32 [[EXT]] 361; 362entry: 363 br label %loop 364 365loop: 366 %iv = phi i8 [ 0, %entry ], [ %iv.next.trunc, %loop.latch ] 367 %iv.ext = zext i8 %iv to i32 368 %cmp = icmp ne i32 %iv.ext, %end 369 br i1 %cmp, label %loop.latch, label %exit 370 371loop.latch: 372 %step.ext = zext i8 %step to i32 373 %iv.next = add i32 %iv.ext, %step.ext 374 %iv.next.trunc = trunc i32 %iv.next to i8 375 br label %loop 376 377exit: 378 %ext = zext i8 %iv to i32 379 ret i32 %ext 380} 381