brintos

brintos / llvm-project-archived public Read only

0
0
Text · 16.2 KiB · 3ac96b8 Raw
408 lines · plain
1; RUN: opt -mtriple=thumbv8.1m.main-none-none-eabi -passes=hardware-loops %s -S -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-MAIN2; RUN: opt -mtriple=thumbv8.1m.main-none-none-eabi -mattr=+fullfp16 -passes=hardware-loops %s -S -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-FP3; RUN: opt -mtriple=thumbv8.1m.main-none-none-eabi -mattr=+fp-armv8,+fullfp16 -passes=hardware-loops %s -S -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-FP644; RUN: opt -mtriple=thumbv8.1m.main-none-none-eabi -mattr=+mve -passes=hardware-loops %s -S -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-MVE5; RUN: opt -mtriple=thumbv8.1m.main-none-none-eabi -mattr=+mve.fp -passes=hardware-loops %s -S -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-MVEFP6; RUN: opt -mtriple=thumbv8.1m.main-none-none-eabi -passes=hardware-loops -disable-arm-loloops=true %s -S -o - | FileCheck %s --check-prefix=DISABLED7 8; DISABLED-NOT: call i32 @llvm.loop.decrement9 10; CHECK-LABEL: skip_call11; CHECK-NOT: call i32 @llvm.start.loop.iterations12; CHECK-NOT: call i32 @llvm.loop.decrement13 14define i32 @skip_call(i32 %n) {15entry:16  %cmp6 = icmp eq i32 %n, 017  br i1 %cmp6, label %while.end, label %while.body.preheader18 19while.body.preheader:20  br label %while.body21 22while.body:23  %i.08 = phi i32 [ %inc1, %while.body ], [ 0, %while.body.preheader ]24  %res.07 = phi i32 [ %add, %while.body ], [ 0, %while.body.preheader ]25  %call = tail call i32 @bar() #226  %add = add nsw i32 %call, %res.0727  %inc1 = add nuw i32 %i.08, 128  %exitcond = icmp eq i32 %inc1, %n29  br i1 %exitcond, label %while.end.loopexit, label %while.body30 31while.end.loopexit:32  br label %while.end33 34while.end:35  %res.0.lcssa = phi i32 [ 0, %entry ], [ %add, %while.end.loopexit ]36  ret i32 %res.0.lcssa37}38 39; CHECK-LABEL: test_target_specific40; CHECK: [[X:%[^ ]+]] = call i32 @llvm.start.loop.iterations.i32(i32 50)41; CHECK: [[COUNT:%[^ ]+]] = phi i32 [ [[X]], %entry ], [ [[LOOP_DEC:%[^ ]+]], %loop ]42; CHECK: [[LOOP_DEC]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[COUNT]], i32 1)43; CHECK: [[CMP:%[^ ]+]] = icmp ne i32 [[LOOP_DEC]], 044; CHECK: br i1 [[CMP]], label %loop, label %exit45 46define i32 @test_target_specific(ptr %a, ptr %b) {47entry:48  br label %loop49loop:50  %acc = phi i32 [ 0, %entry ], [ %res, %loop ]51  %count = phi i32 [ 0, %entry ], [ %count.next, %loop ]52  %addr.a = getelementptr i32, ptr %a, i32 %count53  %addr.b = getelementptr i32, ptr %b, i32 %count54  %load.a = load i32, ptr %addr.a55  %load.b = load i32, ptr %addr.b56  %res = call i32 @llvm.arm.smlad(i32 %load.a, i32 %load.b, i32 %acc)57  %count.next = add nuw i32 %count, 258  %cmp = icmp ne i32 %count.next, 10059  br i1 %cmp, label %loop, label %exit60exit:61  ret i32 %res62}63 64; CHECK-LABEL: test_fabs_f1665; CHECK-MAIN-NOT: call i32 @llvm.start.loop.iterations66; CHECK-MVE-NOT:  call i32 @llvm.start.loop.iterations67; CHECK-FP:       call i32 @llvm.start.loop.iterations.i32(i32 100)68; CHECK-MVEFP:    call i32 @llvm.start.loop.iterations.i32(i32 100)69define void @test_fabs_f16(ptr %a, ptr %b) {70entry:71  br label %loop72loop:73  %count = phi i32 [ 0, %entry ], [ %count.next, %loop ]74  %addr.a = getelementptr half, ptr %a, i32 %count75  %load.a = load half, ptr %addr.a76  %abs = call half @llvm.fabs.f16(half %load.a)77  %addr.b = getelementptr half, ptr %b, i32 %count78  store half %abs, ptr %addr.b79  %count.next = add nuw i32 %count, 180  %cmp = icmp ne i32 %count.next, 10081  br i1 %cmp, label %loop, label %exit82exit:83  ret void84}85 86; CHECK-LABEL: test_fabs87; CHECK-MAIN-NOT: call i32 @llvm.start.loop.iterations88; CHECK-MVE-NOT:  call i32 @llvm.start.loop.iterations89; CHECK-FP:       call i32 @llvm.start.loop.iterations.i32(i32 100)90; CHECK-MVEFP:    call i32 @llvm.start.loop.iterations.i32(i32 100)91 92define float @test_fabs(ptr %a) {93entry:94  br label %loop95loop:96  %acc = phi float [ 0.0, %entry ], [ %res, %loop ]97  %count = phi i32 [ 0, %entry ], [ %count.next, %loop ]98  %addr.a = getelementptr float, ptr %a, i32 %count99  %load.a = load float, ptr %addr.a100  %abs = call float @llvm.fabs.f32(float %load.a)101  %res = fadd float %abs, %acc102  %count.next = add nuw i32 %count, 1103  %cmp = icmp ne i32 %count.next, 100104  br i1 %cmp, label %loop, label %exit105exit:106  ret float %res107}108 109; CHECK-LABEL: test_fabs_64110; CHECK-MAIN-NOT:   call i32 @llvm.start.loop.iterations111; CHECK-MVE-NOT:    call i32 @llvm.start.loop.iterations112; CHECK-FP-NOT:     call i32 @llvm.start.loop.iterations.i32(i32 100)113; CHECK-FP64:       call i32 @llvm.start.loop.iterations.i32(i32 100)114; CHECK-MVEFP-NOT:  call i32 @llvm.start.loop.iterations.i32(i32 100)115define void @test_fabs_64(ptr %a, ptr %b) {116entry:117  br label %loop118loop:119  %count = phi i32 [ 0, %entry ], [ %count.next, %loop ]120  %addr.a = getelementptr double, ptr %a, i32 %count121  %load.a = load double, ptr %addr.a122  %abs = call double @llvm.fabs.f64(double %load.a)123  %addr.b = getelementptr double, ptr %b, i32 %count124  store double %abs, ptr %addr.b125  %count.next = add nuw i32 %count, 1126  %cmp = icmp ne i32 %count.next, 100127  br i1 %cmp, label %loop, label %exit128exit:129  ret void130}131 132; CHECK-LABEL: test_fabs_vec133; CHECK-MVE-NOT: call i32 @llvm.start.loop.iterations134; CHECK-MVEFP: [[X:%[^ ]+]] = call i32 @llvm.start.loop.iterations.i32(i32 100)135; CHECK-MVEFP: [[COUNT:%[^ ]+]] = phi i32 [ [[X]], %entry ], [ [[LOOP_DEC:%[^ ]+]], %loop ]136; CHECK-MVEFP: [[LOOP_DEC]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[COUNT]], i32 1)137; CHECK-MVEFP: [[CMP:%[^ ]+]] = icmp ne i32 [[LOOP_DEC]], 0138; CHECK-MVEFP: br i1 [[CMP]], label %loop, label %exit139define <4 x float> @test_fabs_vec(ptr %a) {140entry:141  br label %loop142loop:143  %acc = phi <4 x float> [ zeroinitializer, %entry ], [ %res, %loop ]144  %count = phi i32 [ 0, %entry ], [ %count.next, %loop ]145  %addr.a = getelementptr <4 x float>, ptr %a, i32 %count146  %load.a = load <4 x float>, ptr %addr.a147  %abs = call <4 x float> @llvm.fabs.v4f32(<4 x float> %load.a)148  %res = fadd <4 x float> %abs, %acc149  %count.next = add nuw i32 %count, 1150  %cmp = icmp ne i32 %count.next, 100151  br i1 %cmp, label %loop, label %exit152exit:153  ret <4 x float> %res154}155 156; CHECK-LABEL: test_log157; CHECK-NOT: call i32 @llvm.start.loop.iterations158; CHECK-NOT: llvm.loop.decrement159define float @test_log(ptr %a) {160entry:161  br label %loop162loop:163  %acc = phi float [ 0.0, %entry ], [ %res, %loop ]164  %count = phi i32 [ 0, %entry ], [ %count.next, %loop ]165  %addr.a = getelementptr float, ptr %a, i32 %count166  %load.a = load float, ptr %addr.a167  %abs = call float @llvm.log.f32(float %load.a)168  %res = fadd float %abs, %acc169  %count.next = add nuw i32 %count, 1170  %cmp = icmp ne i32 %count.next, 100171  br i1 %cmp, label %loop, label %exit172exit:173  ret float %res174}175 176; CHECK-LABEL: test_sqrt_16177; CHECK-MAIN-NOT: call i32 @llvm.start.loop.iterations178; CHECK-MVE-NOT:  call i32 @llvm.start.loop.iterations179; CHECK-FP:       call i32 @llvm.start.loop.iterations.i32(i32 100)180; CHECK-MVEFP:    call i32 @llvm.start.loop.iterations.i32(i32 100)181; CHECK-FP64:     call i32 @llvm.start.loop.iterations.i32(i32 100)182define void @test_sqrt_16(ptr %a, ptr %b) {183entry:184  br label %loop185loop:186  %count = phi i32 [ 0, %entry ], [ %count.next, %loop ]187  %addr.a = getelementptr half, ptr %a, i32 %count188  %load.a = load half, ptr %addr.a189  %sqrt = call half @llvm.sqrt.f16(half %load.a)190  %addr.b = getelementptr half, ptr %b, i32 %count191  store half %sqrt, ptr %addr.b192  %count.next = add nuw i32 %count, 1193  %cmp = icmp ne i32 %count.next, 100194  br i1 %cmp, label %loop, label %exit195exit:196  ret void197}198; CHECK-LABEL: test_sqrt199; CHECK-MAIN-NOT: call i32 @llvm.start.loop.iterations200; CHECK-MVE-NOT: call i32 @llvm.start.loop.iterations201; CHECK-FP: call i32 @llvm.start.loop.iterations202; CHECK-MVEFP: [[X:%[^ ]+]] = call i32 @llvm.start.loop.iterations.i32(i32 100)203; CHECK-MVEFP: [[COUNT:%[^ ]+]] = phi i32 [ [[X]], %entry ], [ [[LOOP_DEC:%[^ ]+]], %loop ]204; CHECK-MVEFP: [[LOOP_DEC]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[COUNT]], i32 1)205; CHECK-MVEFP: [[CMP:%[^ ]+]] = icmp ne i32 [[LOOP_DEC]], 0206; CHECK-MVEFP: br i1 [[CMP]], label %loop, label %exit207define void @test_sqrt(ptr %a, ptr %b) {208entry:209  br label %loop210loop:211  %count = phi i32 [ 0, %entry ], [ %count.next, %loop ]212  %addr.a = getelementptr float, ptr %a, i32 %count213  %load.a = load float, ptr %addr.a214  %sqrt = call float @llvm.sqrt.f32(float %load.a)215  %addr.b = getelementptr float, ptr %b, i32 %count216  store float %sqrt, ptr %addr.b217  %count.next = add nuw i32 %count, 1218  %cmp = icmp ne i32 %count.next, 100219  br i1 %cmp, label %loop, label %exit220exit:221  ret void222}223 224; CHECK-LABEL: test_sqrt_64225; CHECK-MAIN-NOT:   call i32 @llvm.start.loop.iterations226; CHECK-MVE-NOT:    call i32 @llvm.start.loop.iterations227; CHECK-FP-NOT:     call i32 @llvm.start.loop.iterations.i32(i32 100)228; CHECK-MVEFP-NOT:  call i32 @llvm.start.loop.iterations.i32(i32 100)229; CHECK-FP64:       call i32 @llvm.start.loop.iterations.i32(i32 100)230define void @test_sqrt_64(ptr %a, ptr %b) {231entry:232  br label %loop233loop:234  %count = phi i32 [ 0, %entry ], [ %count.next, %loop ]235  %addr.a = getelementptr double, ptr %a, i32 %count236  %load.a = load double, ptr %addr.a237  %sqrt = call double @llvm.sqrt.f64(double %load.a)238  %addr.b = getelementptr double, ptr %b, i32 %count239  store double %sqrt, ptr %addr.b240  %count.next = add nuw i32 %count, 1241  %cmp = icmp ne i32 %count.next, 100242  br i1 %cmp, label %loop, label %exit243exit:244  ret void245}246 247; CHECK-LABEL: test_sqrt_vec248; CHECK-MAIN-NOT: call i32 @llvm.start.loop.iterations249; CHECK-MVE-NOT:  call i32 @llvm.start.loop.iterations250; CHECK-FP:       call i32 @llvm.start.loop.iterations.i32(i32 100)251; CHECK-MVEFP:    call i32 @llvm.start.loop.iterations.i32(i32 100)252define void @test_sqrt_vec(ptr %a, ptr %b) {253entry:254  br label %loop255loop:256  %count = phi i32 [ 0, %entry ], [ %count.next, %loop ]257  %addr.a = getelementptr <4 x float>, ptr %a, i32 %count258  %load.a = load <4 x float>, ptr %addr.a259  %sqrt = call <4 x float> @llvm.sqrt.v4f32(<4 x float> %load.a)260  %addr.b = getelementptr <4 x float>, ptr %b, i32 %count261  store <4 x float> %sqrt, ptr %addr.b262  %count.next = add nuw i32 %count, 1263  %cmp = icmp ne i32 %count.next, 100264  br i1 %cmp, label %loop, label %exit265exit:266  ret void267}268 269; CHECK-LABEL: test_overflow270; CHECK: call i32 @llvm.start.loop.iterations271define i32 @test_overflow(ptr %a, ptr %b) {272entry:273  br label %loop274loop:275  %acc = phi i32 [ 0, %entry ], [ %res, %loop ]276  %count = phi i32 [ 0, %entry ], [ %count.next, %loop ]277  %addr.a = getelementptr i32, ptr %a, i32 %count278  %addr.b = getelementptr i32, ptr %b, i32 %count279  %load.a = load i32, ptr %addr.a280  %load.b = load i32, ptr %addr.b281  %sadd = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %load.a, i32 %load.b)282  %res = extractvalue {i32, i1} %sadd, 0283  %count.next = add nuw i32 %count, 1284  %cmp = icmp ne i32 %count.next, 100285  br i1 %cmp, label %loop, label %exit286exit:287  ret i32 %res288}289 290; TODO: We should be able to generate a qadd/sub291; CHECK-LABEL: test_sat292; CHECK: call i32 @llvm.start.loop.iterations.i32(i32 100)293define i32 @test_sat(ptr %a, ptr %b) {294entry:295  br label %loop296loop:297  %acc = phi i32 [ 0, %entry ], [ %res, %loop ]298  %count = phi i32 [ 0, %entry ], [ %count.next, %loop ]299  %addr.a = getelementptr i32, ptr %a, i32 %count300  %addr.b = getelementptr i32, ptr %b, i32 %count301  %load.a = load i32, ptr %addr.a302  %load.b = load i32, ptr %addr.b303  %res = call i32 @llvm.sadd.sat.i32(i32 %load.a, i32 %load.b)304  %count.next = add nuw i32 %count, 1305  %cmp = icmp ne i32 %count.next, 100306  br i1 %cmp, label %loop, label %exit307exit:308  ret i32 %res309}310 311; CHECK-LABEL: test_masked_i32312; CHECK-NOT: call i32 @llvm.start.loop.iterations313; CHECK-MVEFP: call i32 @llvm.start.loop.iterations314; CHECK-MVE: [[X:%[^ ]+]] = call i32 @llvm.start.loop.iterations.i32(i32 100)315; CHECK-MVE: [[COUNT:%[^ ]+]] = phi i32 [ [[X]], %entry ], [ [[LOOP_DEC:%[^ ]+]], %loop ]316; CHECK-MVE: [[LOOP_DEC]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[COUNT]], i32 1)317; CHECK-MVE: [[CMP:%[^ ]+]] = icmp ne i32 [[LOOP_DEC]], 0318; CHECK-MVE: br i1 [[CMP]], label %loop, label %exit319define arm_aapcs_vfpcc void @test_masked_i32(<4 x i1> %mask, ptr %a, ptr %b, ptr %c, <4 x i32> %passthru) {320entry:321  br label %loop322loop:323  %count = phi i32 [ 0, %entry ], [ %count.next, %loop ]324  %addr.a = getelementptr <4 x i32>, ptr %a, i32 %count325  %addr.b = getelementptr <4 x i32>, ptr %b, i32 %count326  %addr.c = getelementptr <4 x i32>, ptr %c, i32 %count327  %load.a = call <4 x i32> @llvm.masked.load.v4i32.p0(ptr %addr.a, i32 4, <4 x i1> %mask, <4 x i32> %passthru)328  %load.b = call <4 x i32> @llvm.masked.load.v4i32.p0(ptr %addr.b, i32 4, <4 x i1> %mask, <4 x i32> %passthru)329  %res = add <4 x i32> %load.a, %load.b330  call void @llvm.masked.store.v4i32.p0(<4 x i32> %res, ptr %addr.c, i32 4, <4 x i1> %mask)331  %count.next = add nuw i32 %count, 1332  %cmp = icmp ne i32 %count.next, 100333  br i1 %cmp, label %loop, label %exit334exit:335  ret void336}337 338; CHECK-LABEL: test_masked_f32339; CHECK-NOT: call i32 @llvm.start.loop.iterations340; CHECK-MVEFP: call i32 @llvm.start.loop.iterations341; CHECK-MVE: [[X:%[^ ]+]] = call i32 @llvm.start.loop.iterations.i32(i32 100)342; CHECK-MVE: [[COUNT:%[^ ]+]] = phi i32 [ [[X]], %entry ], [ [[LOOP_DEC:%[^ ]+]], %loop ]343; CHECK-MVE: [[LOOP_DEC]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[COUNT]], i32 1)344; CHECK-MVE: [[CMP:%[^ ]+]] = icmp ne i32 [[LOOP_DEC]], 0345; CHECK-MVE: br i1 [[CMP]], label %loop, label %exit346define arm_aapcs_vfpcc void @test_masked_f32(<4 x i1> %mask, ptr %a, ptr %b, ptr %c, <4 x float> %passthru) {347entry:348  br label %loop349loop:350  %count = phi i32 [ 0, %entry ], [ %count.next, %loop ]351  %addr.a = getelementptr <4 x float>, ptr %a, i32 %count352  %addr.b = getelementptr <4 x float>, ptr %b, i32 %count353  %addr.c = getelementptr <4 x float>, ptr %c, i32 %count354  %load.a = call <4 x float> @llvm.masked.load.v4f32.p0(ptr %addr.a, i32 4, <4 x i1> %mask, <4 x float> %passthru)355  %load.b = call <4 x float> @llvm.masked.load.v4f32.p0(ptr %addr.b, i32 4, <4 x i1> %mask, <4 x float> %passthru)356  %res = fadd <4 x float> %load.a, %load.b357  call void @llvm.masked.store.v4f32.p0(<4 x float> %res, ptr %addr.c, i32 4, <4 x i1> %mask)358  %count.next = add nuw i32 %count, 1359  %cmp = icmp ne i32 %count.next, 100360  br i1 %cmp, label %loop, label %exit361exit:362  ret void363}364 365; CHECK-LABEL: test_gather_scatter366; CHECK-NOT: call i32 @llvm.start.loop.iterations367; CHECK-MVEFP: call i32 @llvm.start.loop.iterations368; CHECK-MVE: [[X:%[^ ]+]] = call i32 @llvm.start.loop.iterations.i32(i32 100)369; CHECK-MVE: [[COUNT:%[^ ]+]] = phi i32 [ [[X]], %entry ], [ [[LOOP_DEC:%[^ ]+]], %loop ]370; CHECK-MVE: [[LOOP_DEC]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[COUNT]], i32 1)371; CHECK-MVE: [[CMP:%[^ ]+]] = icmp ne i32 [[LOOP_DEC]], 0372; CHECK-MVE: br i1 [[CMP]], label %loop, label %exit373define arm_aapcs_vfpcc void @test_gather_scatter(<4 x i1> %mask, <4 x ptr> %a, <4 x ptr> %b, <4 x ptr> %c, <4 x float> %passthru) {374entry:375  br label %loop376loop:377  %count = phi i32 [ 0, %entry ], [ %count.next, %loop ]378  %load.a = call <4 x float> @llvm.masked.gather.v4f32.p0(<4 x ptr> %a, i32 4, <4 x i1> %mask, <4 x float> %passthru)379  %load.b = call <4 x float> @llvm.masked.gather.v4f32.p0(<4 x ptr> %b, i32 4, <4 x i1> %mask, <4 x float> %passthru)380  %res = fadd <4 x float> %load.a, %load.b381  call void @llvm.masked.scatter.v4f32.p0(<4 x float> %res, <4 x ptr> %c, i32 4, <4 x i1> %mask)382  %count.next = add nuw i32 %count, 1383  %cmp = icmp ne i32 %count.next, 100384  br i1 %cmp, label %loop, label %exit385exit:386  ret void387}388 389declare i32 @bar(...) local_unnamed_addr #1390declare i32 @llvm.arm.smlad(i32, i32, i32)391declare half @llvm.fabs.f16(half)392declare float @llvm.fabs.f32(float)393declare double @llvm.fabs.f64(double)394declare float @llvm.log.f32(float)395declare <4 x float> @llvm.fabs.v4f32(<4 x float>)396declare half @llvm.sqrt.f16(half)397declare float @llvm.sqrt.f32(float)398declare double @llvm.sqrt.f64(double)399declare <4 x float> @llvm.sqrt.v4f32(<4 x float>)400declare i32 @llvm.sadd.sat.i32(i32, i32)401declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32)402declare <4 x i32> @llvm.masked.load.v4i32.p0(ptr, i32, <4 x i1>, <4 x i32>)403declare void @llvm.masked.store.v4i32.p0(<4 x i32>, ptr, i32, <4 x i1>)404declare <4 x float> @llvm.masked.load.v4f32.p0(ptr, i32, <4 x i1>, <4 x float>)405declare void @llvm.masked.store.v4f32.p0(<4 x float>, ptr, i32, <4 x i1>)406declare <4 x float> @llvm.masked.gather.v4f32.p0(<4 x ptr>, i32, <4 x i1>, <4 x float>)407declare void @llvm.masked.scatter.v4f32.p0(<4 x float>, <4 x ptr>, i32, <4 x i1>)408