brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.3 KiB · 554c248 Raw
338 lines · plain
1; Test loop tuning.2;3; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 -disable-block-placement | FileCheck %s4; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 -disable-block-placement \5; RUN:  | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-Z136 7; Test that strength reduction is applied to addresses with a scale factor,8; but that indexed addressing can still be used.9define void @f1(ptr %dest, i32 %a) {10; CHECK-LABEL: f1:11; CHECK-NOT: sllg12; CHECK: st %r3, 400({{%r[1-5],%r[1-5]}})13; CHECK: br %r1414entry:15  br label %loop16 17loop:18  %index = phi i64 [ 0, %entry ], [ %next, %loop ]19  %ptr = getelementptr i32, ptr %dest, i64 %index20  store i32 %a, ptr %ptr21  %next = add i64 %index, 122  %cmp = icmp ne i64 %next, 10023  br i1 %cmp, label %loop, label %exit24 25exit:26  ret void27}28 29; Test a loop that should be converted into dbr form and then use BRCT.30define void @f2(ptr %src, ptr %dest) {31; CHECK-LABEL: f2:32; CHECK: lhi [[REG:%r[0-5]]], 10033; CHECK: [[LABEL:\.[^:]*]]:{{.*}} %loop34; CHECK: brct [[REG]], [[LABEL]]35; CHECK: br %r1436entry:37  br label %loop38 39loop:40  %count = phi i32 [ 0, %entry ], [ %next, %loop.next ]41  %next = add i32 %count, 142  %val = load volatile i32, ptr %src43  %cmp = icmp eq i32 %val, 044  br i1 %cmp, label %loop.next, label %loop.store45 46loop.store:47  %add = add i32 %val, 148  store volatile i32 %add, ptr %dest49  br label %loop.next50 51loop.next:52  %cont = icmp ne i32 %next, 10053  br i1 %cont, label %loop, label %exit54 55exit:56  ret void57}58 59; Like f2, but for BRCTG.60define void @f3(ptr %src, ptr %dest) {61; CHECK-LABEL: f3:62; CHECK: lghi [[REG:%r[0-5]]], 10063; CHECK: [[LABEL:\.[^:]*]]:{{.*}} %loop64; CHECK: brctg [[REG]], [[LABEL]]65; CHECK: br %r1466entry:67  br label %loop68 69loop:70  %count = phi i64 [ 0, %entry ], [ %next, %loop.next ]71  %next = add i64 %count, 172  %val = load volatile i64, ptr %src73  %cmp = icmp eq i64 %val, 074  br i1 %cmp, label %loop.next, label %loop.store75 76loop.store:77  %add = add i64 %val, 178  store volatile i64 %add, ptr %dest79  br label %loop.next80 81loop.next:82  %cont = icmp ne i64 %next, 10083  br i1 %cont, label %loop, label %exit84 85exit:86  ret void87}88 89; Test a loop with a 64-bit decremented counter in which the 32-bit90; low part of the counter is used after the decrement.  This is an example91; of a subregister use being the only thing that blocks a conversion to BRCTG.92define void @f4(ptr %src, ptr %dest, ptr %dest2, i64 %count) {93; CHECK-LABEL: f4:94; CHECK: aghi [[REG:%r[0-5]]], -195; CHECK: lr [[REG2:%r[0-5]]], [[REG]]96; CHECK: stg [[REG2]],97; CHECK: jne {{\..*}}98; CHECK: br %r1499entry:100  br label %loop101 102loop:103  %left = phi i64 [ %count, %entry ], [ %next, %loop.next ]104  store volatile i64 %left, ptr %dest2105  %val = load volatile i32, ptr %src106  %cmp = icmp eq i32 %val, 0107  br i1 %cmp, label %loop.next, label %loop.store108 109loop.store:110  %add = add i32 %val, 1111  store volatile i32 %add, ptr %dest112  br label %loop.next113 114loop.next:115  %next = add i64 %left, -1116  %ext = zext i32 %val to i64117  %shl = shl i64 %ext, 32118  %and = and i64 %next, 4294967295119  %or = or i64 %shl, %and120  store volatile i64 %or, ptr %dest2121  %cont = icmp ne i64 %next, 0122  br i1 %cont, label %loop, label %exit123 124exit:125  ret void126}127 128; Test that negative offsets are avoided for loads of floating point.129%s.float = type { float, float, float }130define void @f5(ptr nocapture %a,131                ptr nocapture readonly %b,132                i32 zeroext %S) {133; CHECK-Z13-LABEL: f5:134; CHECK-Z13-NOT: -{{[0-9]+}}(%r135 136entry:137  %cmp9 = icmp eq i32 %S, 0138  br i1 %cmp9, label %for.cond.cleanup, label %for.body.preheader139 140for.body.preheader:                 ; preds = %entry141  br label %for.body142 143for.cond.cleanup.loopexit:          ; preds = %for.body144  br label %for.cond.cleanup145 146for.cond.cleanup:                   ; preds = %for.cond.cleanup.loopexit, %entry147  ret void148 149for.body:                           ; preds = %for.body.preheader, %for.body150  %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %for.body.preheader ]151  %a1 = getelementptr inbounds %s.float, ptr %b, i64 %indvars.iv, i32 0152  %tmp = load float, ptr %a1, align 4153  %b4 = getelementptr inbounds %s.float, ptr %b, i64 %indvars.iv, i32 1154  %tmp1 = load float, ptr %b4, align 4155  %add = fadd float %tmp, %tmp1156  %c = getelementptr inbounds %s.float, ptr %b, i64 %indvars.iv, i32 2157  %tmp2 = load float, ptr %c, align 4158  %add7 = fadd float %add, %tmp2159  %a10 = getelementptr inbounds %s.float, ptr %a, i64 %indvars.iv, i32 0160  store float %add7, ptr %a10, align 4161  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1162  %lftr.wideiv = trunc i64 %indvars.iv.next to i32163  %exitcond = icmp eq i32 %lftr.wideiv, %S164  br i1 %exitcond, label %for.cond.cleanup.loopexit, label %for.body165}166 167; Test that negative offsets are avoided for loads of double.168%s.double = type { double, double, double }169define void @f6(ptr nocapture %a,170                ptr nocapture readonly %b,171                i32 zeroext %S) {172; CHECK-Z13-LABEL: f6:173; CHECK-Z13-NOT: -{{[0-9]+}}(%r174entry:175  %cmp9 = icmp eq i32 %S, 0176  br i1 %cmp9, label %for.cond.cleanup, label %for.body.preheader177 178for.body.preheader:                  ; preds = %entry179  br label %for.body180 181for.cond.cleanup.loopexit:           ; preds = %for.body182  br label %for.cond.cleanup183 184for.cond.cleanup:                    ; preds = %for.cond.cleanup.loopexit, %entry185  ret void186 187for.body:                            ; preds = %for.body.preheader, %for.body188  %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %for.body.preheader ]189  %a1 = getelementptr inbounds %s.double, ptr %b, i64 %indvars.iv, i32 0190  %tmp = load double, ptr %a1, align 4191  %b4 = getelementptr inbounds %s.double, ptr %b, i64 %indvars.iv, i32 1192  %tmp1 = load double, ptr %b4, align 4193  %add = fadd double %tmp, %tmp1194  %c = getelementptr inbounds %s.double, ptr %b, i64 %indvars.iv, i32 2195  %tmp2 = load double, ptr %c, align 4196  %add7 = fadd double %add, %tmp2197  %a10 = getelementptr inbounds %s.double, ptr %a, i64 %indvars.iv, i32 0198  store double %add7, ptr %a10, align 4199  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1200  %lftr.wideiv = trunc i64 %indvars.iv.next to i32201  %exitcond = icmp eq i32 %lftr.wideiv, %S202  br i1 %exitcond, label %for.cond.cleanup.loopexit, label %for.body203}204 205; Test that negative offsets are avoided for memory accesses of vector type.206%s.vec = type { <4 x i32>, <4 x i32>, <4 x i32> }207define void @f7(ptr nocapture %a,208                ptr nocapture readonly %b,209                i32 zeroext %S) {210; CHECK-Z13-LABEL: f7:211; CHECK-Z13-NOT: -{{[0-9]+}}(%r212entry:213  %cmp9 = icmp eq i32 %S, 0214  br i1 %cmp9, label %for.cond.cleanup, label %for.body.preheader215 216for.body.preheader:                 ; preds = %entry217  br label %for.body218 219for.cond.cleanup.loopexit:          ; preds = %for.body220  br label %for.cond.cleanup221 222for.cond.cleanup:                   ; preds = %for.cond.cleanup.loopexit, %entry223  ret void224 225for.body:                           ; preds = %for.body.preheader, %for.body226  %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %for.body.preheader ]227  %a1 = getelementptr inbounds %s.vec, ptr %b, i64 %indvars.iv, i32 0228  %tmp = load <4 x i32>, ptr %a1, align 4229  %b4 = getelementptr inbounds %s.vec, ptr %b, i64 %indvars.iv, i32 1230  %tmp1 = load <4 x i32>, ptr %b4, align 4231  %add = add <4 x i32> %tmp1, %tmp232  %c = getelementptr inbounds %s.vec, ptr %b, i64 %indvars.iv, i32 2233  %tmp2 = load <4 x i32>, ptr %c, align 4234  %add7 = add <4 x i32> %add, %tmp2235  %a10 = getelementptr inbounds %s.vec, ptr %a, i64 %indvars.iv, i32 0236  store <4 x i32> %add7, ptr %a10, align 4237  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1238  %lftr.wideiv = trunc i64 %indvars.iv.next to i32239  %exitcond = icmp eq i32 %lftr.wideiv, %S240  br i1 %exitcond, label %for.cond.cleanup.loopexit, label %for.body241}242 243; Test that a memcpy loop does not get a lot of lays before each mvc (D12 and no index-reg).244%0 = type { %1, ptr }245%1 = type { ptr, ptr }246%2 = type <{ %3, i32, [4 x i8] }>247%3 = type { ptr, ptr, ptr }248 249declare void @llvm.memcpy.p0.p0.i64(ptr nocapture writeonly, ptr nocapture readonly, i64, i1) #0250 251define void @f8() {252; CHECK-Z13-LABEL: f8:253; CHECK-Z13: mvc254; CHECK-Z13-NEXT: mvc255; CHECK-Z13-NEXT: mvc256; CHECK-Z13-NEXT: mvc257 258bb:259  %tmp = load ptr, ptr undef, align 8260  br i1 undef, label %bb2, label %bb1261 262bb1:                                              ; preds = %bb263  br label %bb2264 265bb2:                                              ; preds = %bb1, %bb266  %tmp3 = phi ptr [ %tmp, %bb ], [ undef, %bb1 ]267  %tmp4 = phi ptr [ undef, %bb ], [ undef, %bb1 ]268  br label %bb5269 270bb5:                                              ; preds = %bb5, %bb2271  %tmp6 = phi ptr [ %tmp21, %bb5 ], [ %tmp3, %bb2 ]272  %tmp7 = phi ptr [ %tmp20, %bb5 ], [ %tmp4, %bb2 ]273  %tmp8 = getelementptr inbounds %0, ptr %tmp7, i64 -1274  %tmp9 = getelementptr inbounds %0, ptr %tmp6, i64 -1275  tail call void @llvm.memcpy.p0.p0.i64(ptr align 8 %tmp9, ptr align 8 %tmp8, i64 24, i1 false)276  %tmp12 = getelementptr inbounds %0, ptr %tmp7, i64 -2277  %tmp13 = getelementptr inbounds %0, ptr %tmp6, i64 -2278  tail call void @llvm.memcpy.p0.p0.i64(ptr align 8 %tmp13, ptr align 8 %tmp12, i64 24, i1 false)279  %tmp16 = getelementptr inbounds %0, ptr %tmp7, i64 -3280  %tmp17 = getelementptr inbounds %0, ptr %tmp6, i64 -3281  tail call void @llvm.memcpy.p0.p0.i64(ptr align 8 %tmp17, ptr align 8 %tmp16, i64 24, i1 false)282  %tmp20 = getelementptr inbounds %0, ptr %tmp7, i64 -4283  %tmp21 = getelementptr inbounds %0, ptr %tmp6, i64 -4284  tail call void @llvm.memcpy.p0.p0.i64(ptr align 8 %tmp21, ptr align 8 %tmp20, i64 24, i1 false)285  br label %bb5286}287 288; Test that a chsi does not need an aghik inside the loop (no index reg)289define void @f9() {290; CHECK-Z13-LABEL: f9:291; CHECK-Z13: # =>This Inner Loop Header: Depth=1292; CHECK-Z13-NOT: aghik293; CHECK-Z13: chsi294 295entry:296  br label %for.body.i63297 298for.body.i63:                                     ; preds = %for.inc.i, %entry299  %indvars.iv155.i = phi i64 [ 0, %entry ], [ %indvars.iv.next156.i.3, %for.inc.i ]300  %arrayidx.i62 = getelementptr inbounds i32, ptr undef, i64 %indvars.iv155.i301  %tmp = load i32, ptr %arrayidx.i62, align 4302  %cmp9.i = icmp eq i32 %tmp, 0303  br i1 %cmp9.i, label %for.inc.i, label %if.then10.i304 305if.then10.i:                                      ; preds = %for.body.i63306  unreachable307 308for.inc.i:                                        ; preds = %for.body.i63309  %indvars.iv.next156.i = or i64 %indvars.iv155.i, 1310  %arrayidx.i62.1 = getelementptr inbounds i32, ptr undef, i64 %indvars.iv.next156.i311  %tmp1 = load i32, ptr %arrayidx.i62.1, align 4312  %indvars.iv.next156.i.3 = add nsw i64 %indvars.iv155.i, 4313  br label %for.body.i63314}315 316; Test that offsets are in range for i128 memory accesses.317define void @fun10() {318; CHECK-Z13-LABEL: fun10:319; CHECK-Z13: # =>This Inner Loop Header: Depth=1320; CHECK-Z13-NOT: lay321entry:322  %A1 = alloca [3 x [7 x [10 x i128]]], align 8323  br label %for.body324 325for.body:                        ; preds = %for.body, %entry326  %IV = phi i64 [ 0, %entry ], [ %IV.next, %for.body ]327  %Addr1 = getelementptr inbounds [3 x [7 x [10 x i128]]], ptr %A1, i64 0, i64 %IV, i64 6, i64 6328  store i128 17174966165894859678, ptr %Addr1, align 8329  %Addr2 = getelementptr inbounds [3 x [7 x [10 x i128]]], ptr %A1, i64 0, i64 %IV, i64 6, i64 8330  store i128 17174966165894859678, ptr %Addr2, align 8331  %IV.next = add nuw nsw i64 %IV, 1332  %exitcond.not.i.i = icmp eq i64 %IV.next, 3333  br i1 %exitcond.not.i.i, label %exit, label %for.body334 335exit:                        ; preds = %for.body336  unreachable337}338