brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.4 KiB · ed49dc5 Raw
153 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --filter-out-after "^scalar.ph:"2; RUN: opt -passes=loop-vectorize < %s -S -o - | FileCheck %s3 4target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"5target triple = "aarch64-unknown-linux-gnu"6 7; Test cases to make sure LV & loop versioning can handle loops with8; multiple exiting branches.9 10; Multiple branches exiting the loop to a unique exit block.11define void @multiple_exits_unique_exit_block(ptr %A, ptr %B, i32 %N) #0 {12; CHECK-LABEL: @multiple_exits_unique_exit_block(13; CHECK-NEXT:  entry:14; CHECK-NEXT:    [[A2:%.*]] = ptrtoint ptr [[A:%.*]] to i6415; CHECK-NEXT:    [[B1:%.*]] = ptrtoint ptr [[B:%.*]] to i6416; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[N:%.*]], i32 999)17; CHECK-NEXT:    [[TMP0:%.*]] = add nuw nsw i32 [[UMIN]], 118; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.vscale.i32()19; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw i32 [[TMP1]], 320; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ule i32 [[TMP0]], [[TMP2]]21; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_MEMCHECK:%.*]]22; CHECK:       vector.memcheck:23; CHECK-NEXT:    [[TMP3:%.*]] = call i64 @llvm.vscale.i64()24; CHECK-NEXT:    [[TMP4:%.*]] = mul nuw i64 [[TMP3]], 425; CHECK-NEXT:    [[TMP5:%.*]] = mul i64 [[TMP4]], 826; CHECK-NEXT:    [[TMP6:%.*]] = sub i64 [[B1]], [[A2]]27; CHECK-NEXT:    [[DIFF_CHECK:%.*]] = icmp ult i64 [[TMP6]], [[TMP5]]28; CHECK-NEXT:    br i1 [[DIFF_CHECK]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]29; CHECK:       vector.ph:30; CHECK-NEXT:    [[TMP7:%.*]] = call i32 @llvm.vscale.i32()31; CHECK-NEXT:    [[TMP8:%.*]] = mul nuw i32 [[TMP7]], 832; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i32 [[TMP0]], [[TMP8]]33; CHECK-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[N_MOD_VF]], 034; CHECK-NEXT:    [[TMP10:%.*]] = select i1 [[TMP9]], i32 [[TMP8]], i32 [[N_MOD_VF]]35; CHECK-NEXT:    [[N_VEC:%.*]] = sub i32 [[TMP0]], [[TMP10]]36; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]37; CHECK:       vector.body:38; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]39; CHECK-NEXT:    [[TMP19:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INDEX]]40; CHECK-NEXT:    [[TMP22:%.*]] = call i64 @llvm.vscale.i64()41; CHECK-NEXT:    [[TMP23:%.*]] = shl nuw i64 [[TMP22]], 242; CHECK-NEXT:    [[TMP24:%.*]] = getelementptr inbounds i32, ptr [[TMP19]], i64 [[TMP23]]43; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <vscale x 4 x i32>, ptr [[TMP19]], align 444; CHECK-NEXT:    [[WIDE_LOAD3:%.*]] = load <vscale x 4 x i32>, ptr [[TMP24]], align 445; CHECK-NEXT:    [[TMP25:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INDEX]]46; CHECK-NEXT:    [[TMP28:%.*]] = call i64 @llvm.vscale.i64()47; CHECK-NEXT:    [[TMP29:%.*]] = shl nuw i64 [[TMP28]], 248; CHECK-NEXT:    [[TMP30:%.*]] = getelementptr inbounds i32, ptr [[TMP25]], i64 [[TMP29]]49; CHECK-NEXT:    store <vscale x 4 x i32> [[WIDE_LOAD]], ptr [[TMP25]], align 450; CHECK-NEXT:    store <vscale x 4 x i32> [[WIDE_LOAD3]], ptr [[TMP30]], align 451; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], [[TMP8]]52; CHECK-NEXT:    [[TMP31:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]53; CHECK-NEXT:    br i1 [[TMP31]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]54; CHECK:       middle.block:55; CHECK-NEXT:    br label [[SCALAR_PH]]56; CHECK:       scalar.ph:57;58entry:59  br label %loop.header60 61loop.header:62  %iv = phi i32 [ 0, %entry ], [ %iv.next, %for.body ]63  %cond.0 = icmp eq i32 %iv, %N64  br i1 %cond.0, label %exit, label %for.body65 66for.body:67  %A.gep = getelementptr inbounds i32, ptr %A, i32 %iv68  %lv = load i32, ptr %A.gep, align 469  %B.gep = getelementptr inbounds i32, ptr %B, i32 %iv70  store i32 %lv, ptr %B.gep, align 471  %iv.next = add nuw i32 %iv, 172  %cond.1 = icmp ult i32 %iv.next, 100073  br i1 %cond.1, label %loop.header, label %exit74 75exit:76  ret void77}78 79 80; Multiple branches exiting the loop to different blocks.81define i32 @multiple_exits_multiple_exit_blocks(ptr %A, ptr %B, i32 %N) #0 {82; CHECK-LABEL: @multiple_exits_multiple_exit_blocks(83; CHECK-NEXT:  entry:84; CHECK-NEXT:    [[A2:%.*]] = ptrtoint ptr [[A:%.*]] to i6485; CHECK-NEXT:    [[B1:%.*]] = ptrtoint ptr [[B:%.*]] to i6486; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[N:%.*]], i32 999)87; CHECK-NEXT:    [[TMP0:%.*]] = add nuw nsw i32 [[UMIN]], 188; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.vscale.i32()89; CHECK-NEXT:    [[TMP2:%.*]] = shl nuw i32 [[TMP1]], 390; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ule i32 [[TMP0]], [[TMP2]]91; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_MEMCHECK:%.*]]92; CHECK:       vector.memcheck:93; CHECK-NEXT:    [[TMP3:%.*]] = call i64 @llvm.vscale.i64()94; CHECK-NEXT:    [[TMP4:%.*]] = mul nuw i64 [[TMP3]], 495; CHECK-NEXT:    [[TMP5:%.*]] = mul i64 [[TMP4]], 896; CHECK-NEXT:    [[TMP6:%.*]] = sub i64 [[B1]], [[A2]]97; CHECK-NEXT:    [[DIFF_CHECK:%.*]] = icmp ult i64 [[TMP6]], [[TMP5]]98; CHECK-NEXT:    br i1 [[DIFF_CHECK]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]99; CHECK:       vector.ph:100; CHECK-NEXT:    [[TMP7:%.*]] = call i32 @llvm.vscale.i32()101; CHECK-NEXT:    [[TMP8:%.*]] = mul nuw i32 [[TMP7]], 8102; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i32 [[TMP0]], [[TMP8]]103; CHECK-NEXT:    [[TMP9:%.*]] = icmp eq i32 [[N_MOD_VF]], 0104; CHECK-NEXT:    [[TMP10:%.*]] = select i1 [[TMP9]], i32 [[TMP8]], i32 [[N_MOD_VF]]105; CHECK-NEXT:    [[N_VEC:%.*]] = sub i32 [[TMP0]], [[TMP10]]106; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]107; CHECK:       vector.body:108; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]109; CHECK-NEXT:    [[TMP19:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[INDEX]]110; CHECK-NEXT:    [[TMP22:%.*]] = call i64 @llvm.vscale.i64()111; CHECK-NEXT:    [[TMP23:%.*]] = shl nuw i64 [[TMP22]], 2112; CHECK-NEXT:    [[TMP24:%.*]] = getelementptr inbounds i32, ptr [[TMP19]], i64 [[TMP23]]113; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <vscale x 4 x i32>, ptr [[TMP19]], align 4114; CHECK-NEXT:    [[WIDE_LOAD3:%.*]] = load <vscale x 4 x i32>, ptr [[TMP24]], align 4115; CHECK-NEXT:    [[TMP25:%.*]] = getelementptr inbounds i32, ptr [[B]], i32 [[INDEX]]116; CHECK-NEXT:    [[TMP28:%.*]] = call i64 @llvm.vscale.i64()117; CHECK-NEXT:    [[TMP29:%.*]] = shl nuw i64 [[TMP28]], 2118; CHECK-NEXT:    [[TMP30:%.*]] = getelementptr inbounds i32, ptr [[TMP25]], i64 [[TMP29]]119; CHECK-NEXT:    store <vscale x 4 x i32> [[WIDE_LOAD]], ptr [[TMP25]], align 4120; CHECK-NEXT:    store <vscale x 4 x i32> [[WIDE_LOAD3]], ptr [[TMP30]], align 4121; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], [[TMP8]]122; CHECK-NEXT:    [[TMP31:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]123; CHECK-NEXT:    br i1 [[TMP31]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]124; CHECK:       middle.block:125; CHECK-NEXT:    br label [[SCALAR_PH]]126; CHECK:       scalar.ph:127;128entry:129  br label %loop.header130 131loop.header:132  %iv = phi i32 [ 0, %entry ], [ %iv.next, %for.body ]133  %cond.0 = icmp eq i32 %iv, %N134  br i1 %cond.0, label %exit.0, label %for.body135 136for.body:137  %A.gep = getelementptr inbounds i32, ptr %A, i32 %iv138  %lv = load i32, ptr %A.gep, align 4139  %B.gep = getelementptr inbounds i32, ptr %B, i32 %iv140  store i32 %lv, ptr %B.gep, align 4141  %iv.next = add nuw i32 %iv, 1142  %cond.1 = icmp ult i32 %iv.next, 1000143  br i1 %cond.1, label %loop.header, label %exit.1144 145exit.0:146  ret i32 1147 148exit.1:149  ret i32 2150}151 152attributes #0 = { "target-features"="+sve2" }153