@@ -425,3 +425,63 @@ loop:
425425exit:
426426 ret void
427427}
428+
429+ define void @hoist_previous_value_and_operand_load (ptr %dst , i64 %mask ) {
430+ ; CHECK-LABEL: @hoist_previous_value_and_operand_load(
431+ ; CHECK-NEXT: bb:
432+ ; CHECK-NEXT: br label [[LOOP:%.*]]
433+ ; CHECK: vector.ph:
434+ ; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
435+ ; CHECK: vector.body:
436+ ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[LOOP]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
437+ ; CHECK-NEXT: [[VECTOR_RECUR:%.*]] = phi <4 x i32> [ <i32 poison, i32 poison, i32 poison, i32 1>, [[LOOP]] ], [ [[TMP2:%.*]], [[VECTOR_BODY]] ]
438+ ; CHECK-NEXT: [[VECTOR_RECUR1:%.*]] = phi <4 x i32> [ <i32 poison, i32 poison, i32 poison, i32 0>, [[LOOP]] ], [ [[TMP4:%.*]], [[VECTOR_BODY]] ]
439+ ; CHECK-NEXT: [[OFFSET_IDX:%.*]] = add i64 1, [[INDEX]]
440+ ; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i32, ptr [[DST:%.*]], i64 [[OFFSET_IDX]]
441+ ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT:%.*]] = load i32, ptr [[DST]], align 4
442+ ; CHECK-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i32> poison, i32 [[VECTOR_RECUR_EXTRACT]], i64 0
443+ ; CHECK-NEXT: [[TMP2]] = shufflevector <4 x i32> [[BROADCAST_SPLATINSERT]], <4 x i32> poison, <4 x i32> zeroinitializer
444+ ; CHECK-NEXT: [[TMP12:%.*]] = shufflevector <4 x i32> [[VECTOR_RECUR]], <4 x i32> [[TMP2]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
445+ ; CHECK-NEXT: [[TMP4]] = or <4 x i32> [[TMP12]], splat (i32 3)
446+ ; CHECK-NEXT: [[TMP13:%.*]] = shufflevector <4 x i32> [[VECTOR_RECUR1]], <4 x i32> [[TMP4]], <4 x i32> <i32 3, i32 4, i32 5, i32 6>
447+ ; CHECK-NEXT: store <4 x i32> [[TMP13]], ptr [[TMP0]], align 4
448+ ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
449+ ; CHECK-NEXT: [[TMP11:%.*]] = icmp eq i64 [[INDEX_NEXT]], 336
450+ ; CHECK-NEXT: br i1 [[TMP11]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP7:![0-9]+]]
451+ ; CHECK: middle.block:
452+ ; CHECK-NEXT: [[VECTOR_RECUR_EXTRACT2:%.*]] = extractelement <4 x i32> [[TMP4]], i32 3
453+ ; CHECK-NEXT: br label [[SCALAR_PH:%.*]]
454+ ; CHECK: scalar.ph:
455+ ; CHECK-NEXT: br label [[LOOP1:%.*]]
456+ ; CHECK: loop:
457+ ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 337, [[SCALAR_PH]] ], [ [[ADD:%.*]], [[LOOP1]] ]
458+ ; CHECK-NEXT: [[FOR_1:%.*]] = phi i32 [ [[VECTOR_RECUR_EXTRACT]], [[SCALAR_PH]] ], [ [[TRUNC:%.*]], [[LOOP1]] ]
459+ ; CHECK-NEXT: [[FOR_2:%.*]] = phi i32 [ [[VECTOR_RECUR_EXTRACT2]], [[SCALAR_PH]] ], [ [[OR:%.*]], [[LOOP1]] ]
460+ ; CHECK-NEXT: [[OR]] = or i32 [[FOR_1]], 3
461+ ; CHECK-NEXT: [[ADD]] = add i64 [[IV]], 1
462+ ; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV]]
463+ ; CHECK-NEXT: store i32 [[FOR_2]], ptr [[GEP]], align 4
464+ ; CHECK-NEXT: [[ICMP:%.*]] = icmp ult i64 [[IV]], 337
465+ ; CHECK-NEXT: [[TRUNC]] = load i32, ptr [[DST]], align 4
466+ ; CHECK-NEXT: br i1 [[ICMP]], label [[LOOP1]], label [[EXIT:%.*]], !llvm.loop [[LOOP8:![0-9]+]]
467+ ; CHECK: exit:
468+ ; CHECK-NEXT: ret void
469+ ;
470+ bb:
471+ br label %loop
472+
473+ loop:
474+ %iv = phi i64 [ 1 , %bb ], [ %add , %loop ]
475+ %for.1 = phi i32 [ 1 , %bb ], [ %trunc , %loop ]
476+ %for.2 = phi i32 [ 0 , %bb ], [ %or , %loop ]
477+ %or = or i32 %for.1 , 3
478+ %add = add i64 %iv , 1
479+ %gep = getelementptr inbounds i32 , ptr %dst , i64 %iv
480+ store i32 %for.2 , ptr %gep , align 4
481+ %icmp = icmp ult i64 %iv , 337
482+ %trunc = load i32 , ptr %dst
483+ br i1 %icmp , label %loop , label %exit
484+
485+ exit:
486+ ret void
487+ }
0 commit comments