Home | History | Annotate | Download | only in AArch64
      1 ; REQUIRES: asserts
      2 ; RUN: llc < %s -mtriple=arm64-linux-gnu -mcpu=cortex-a53 -pre-RA-sched=source -enable-misched -verify-misched -debug-only=misched -o - 2>&1 > /dev/null | FileCheck %s
      3 ;
      4 ; The Cortex-A53 machine model will cause the MADD instruction to be scheduled
      5 ; much higher than the ADD instructions in order to hide latency. When not
      6 ; specifying a subtarget, the MADD will remain near the end of the block.
      7 ;
      8 ; CHECK: ********** MI Scheduling **********
      9 ; CHECK: main
     10 ; CHECK: *** Final schedule for BB#2 ***
     11 ; CHECK: MADDWrrr
     12 ; CHECK: ADDWri
     13 ; CHECK: ********** INTERVALS **********
     14 @main.x = private unnamed_addr constant [8 x i32] [i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1], align 4
     15 @main.y = private unnamed_addr constant [8 x i32] [i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2], align 4
     16 
     17 ; Function Attrs: nounwind
     18 define i32 @main() #0 {
     19 entry:
     20   %retval = alloca i32, align 4
     21   %x = alloca [8 x i32], align 4
     22   %y = alloca [8 x i32], align 4
     23   %i = alloca i32, align 4
     24   %xx = alloca i32, align 4
     25   %yy = alloca i32, align 4
     26   store i32 0, i32* %retval
     27   %0 = bitcast [8 x i32]* %x to i8*
     28   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* bitcast ([8 x i32]* @main.x to i8*), i64 32, i32 4, i1 false)
     29   %1 = bitcast [8 x i32]* %y to i8*
     30   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* bitcast ([8 x i32]* @main.y to i8*), i64 32, i32 4, i1 false)
     31   store i32 0, i32* %xx, align 4
     32   store i32 0, i32* %yy, align 4
     33   store i32 0, i32* %i, align 4
     34   br label %for.cond
     35 
     36 for.cond:                                         ; preds = %for.inc, %entry
     37   %2 = load i32, i32* %i, align 4
     38   %cmp = icmp slt i32 %2, 8
     39   br i1 %cmp, label %for.body, label %for.end
     40 
     41 for.body:                                         ; preds = %for.cond
     42   %3 = load i32, i32* %i, align 4
     43   %idxprom = sext i32 %3 to i64
     44   %arrayidx = getelementptr inbounds [8 x i32], [8 x i32]* %x, i32 0, i64 %idxprom
     45   %4 = load i32, i32* %arrayidx, align 4
     46   %add = add nsw i32 %4, 1
     47   store i32 %add, i32* %xx, align 4
     48   %5 = load i32, i32* %xx, align 4
     49   %add1 = add nsw i32 %5, 12
     50   store i32 %add1, i32* %xx, align 4
     51   %6 = load i32, i32* %xx, align 4
     52   %add2 = add nsw i32 %6, 23
     53   store i32 %add2, i32* %xx, align 4
     54   %7 = load i32, i32* %xx, align 4
     55   %add3 = add nsw i32 %7, 34
     56   store i32 %add3, i32* %xx, align 4
     57   %8 = load i32, i32* %i, align 4
     58   %idxprom4 = sext i32 %8 to i64
     59   %arrayidx5 = getelementptr inbounds [8 x i32], [8 x i32]* %y, i32 0, i64 %idxprom4
     60   %9 = load i32, i32* %arrayidx5, align 4
     61   %10 = load i32, i32* %yy, align 4
     62   %mul = mul nsw i32 %10, %9
     63   store i32 %mul, i32* %yy, align 4
     64   br label %for.inc
     65 
     66 for.inc:                                          ; preds = %for.body
     67   %11 = load i32, i32* %i, align 4
     68   %inc = add nsw i32 %11, 1
     69   store i32 %inc, i32* %i, align 4
     70   br label %for.cond
     71 
     72 for.end:                                          ; preds = %for.cond
     73   %12 = load i32, i32* %xx, align 4
     74   %13 = load i32, i32* %yy, align 4
     75   %add6 = add nsw i32 %12, %13
     76   ret i32 %add6
     77 }
     78 
     79 
     80 ; The Cortex-A53 machine model will cause the FDIVvvv_42 to be raised to
     81 ; hide latency. Whereas normally there would only be a single FADDvvv_4s
     82 ; after it, this test checks to make sure there are more than one.
     83 ;
     84 ; CHECK: ********** MI Scheduling **********
     85 ; CHECK: neon4xfloat:BB#0
     86 ; CHECK: *** Final schedule for BB#0 ***
     87 ; CHECK: FDIVv4f32
     88 ; CHECK: FADDv4f32
     89 ; CHECK: FADDv4f32
     90 ; CHECK: ********** INTERVALS **********
     91 define <4 x float> @neon4xfloat(<4 x float> %A, <4 x float> %B) {
     92         %tmp1 = fadd <4 x float> %A, %B;
     93         %tmp2 = fadd <4 x float> %A, %tmp1;
     94         %tmp3 = fadd <4 x float> %A, %tmp2;
     95         %tmp4 = fadd <4 x float> %A, %tmp3;
     96         %tmp5 = fadd <4 x float> %A, %tmp4;
     97         %tmp6 = fadd <4 x float> %A, %tmp5;
     98         %tmp7 = fadd <4 x float> %A, %tmp6;
     99         %tmp8 = fadd <4 x float> %A, %tmp7;
    100         %tmp9 = fdiv <4 x float> %A, %B;
    101         %tmp10 = fadd <4 x float> %tmp8, %tmp9;
    102 
    103         ret <4 x float> %tmp10
    104 }
    105 
    106 ; Function Attrs: nounwind
    107 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1) #1
    108 
    109 attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
    110 attributes #1 = { nounwind }
    111 
    112 
    113 ; Regression Test for PR19761
    114 ;   [ARM64] Cortex-a53 schedule mode can't handle NEON post-increment load
    115 ;
    116 ; Nothing explicit to check other than llc not crashing.
    117 define { <16 x i8>, <16 x i8> } @test_v16i8_post_imm_ld2(i8* %A, i8** %ptr) {
    118   %ld2 = tail call { <16 x i8>, <16 x i8> } @llvm.aarch64.neon.ld2.v16i8.p0i8(i8* %A)
    119   %tmp = getelementptr i8, i8* %A, i32 32
    120   store i8* %tmp, i8** %ptr
    121   ret { <16 x i8>, <16 x i8> } %ld2
    122 }
    123 
    124 declare { <16 x i8>, <16 x i8> } @llvm.aarch64.neon.ld2.v16i8.p0i8(i8*)
    125 
    126 ; Regression Test for PR20057.
    127 ;
    128 ; Cortex-A53 machine model stalls on A53UnitFPMDS contention. Instructions that
    129 ; are otherwise ready are jammed in the pending queue.
    130 ; CHECK: ********** MI Scheduling **********
    131 ; CHECK: testResourceConflict
    132 ; CHECK: *** Final schedule for BB#0 ***
    133 ; CHECK: BRK
    134 ; CHECK: ********** INTERVALS **********
    135 define void @testResourceConflict(float* %ptr) {
    136 entry:
    137   %add1 = fadd float undef, undef
    138   %mul2 = fmul float undef, undef
    139   %add3 = fadd float %mul2, undef
    140   %mul4 = fmul float undef, %add3
    141   %add5 = fadd float %mul4, undef
    142   %sub6 = fsub float 0.000000e+00, undef
    143   %sub7 = fsub float %add5, undef
    144   %div8 = fdiv float 1.000000e+00, undef
    145   %mul9 = fmul float %div8, %sub7
    146   %mul14 = fmul float %sub6, %div8
    147   %mul10 = fsub float -0.000000e+00, %mul14
    148   %mul15 = fmul float undef, %div8
    149   %mul11 = fsub float -0.000000e+00, %mul15
    150   %mul12 = fmul float 0.000000e+00, %div8
    151   %mul13 = fmul float %add1, %mul9
    152   %mul21 = fmul float %add5, %mul11
    153   %add22 = fadd float %mul13, %mul21
    154   store float %add22, float* %ptr, align 4
    155   %mul28 = fmul float %add1, %mul10
    156   %mul33 = fmul float %add5, %mul12
    157   %add34 = fadd float %mul33, %mul28
    158   store float %add34, float* %ptr, align 4
    159   %mul240 = fmul float undef, %mul9
    160   %add246 = fadd float %mul240, undef
    161   store float %add246, float* %ptr, align 4
    162   %mul52 = fmul float undef, %mul10
    163   %mul57 = fmul float undef, %mul12
    164   %add58 = fadd float %mul57, %mul52
    165   store float %add58, float* %ptr, align 4
    166   %mul27 = fmul float 0.000000e+00, %mul9
    167   %mul81 = fmul float undef, %mul10
    168   %add82 = fadd float %mul27, %mul81
    169   store float %add82, float* %ptr, align 4
    170   call void @llvm.trap()
    171   unreachable
    172 }
    173 
    174 declare void @llvm.trap()
    175 
    176 ; Regression test for PR20057: "permanent hazard"'
    177 ; Resource contention on LDST.
    178 ; CHECK: ********** MI Scheduling **********
    179 ; CHECK: testLdStConflict
    180 ; CHECK: *** Final schedule for BB#1 ***
    181 ; CHECK: LD4Fourv2d
    182 ; CHECK: STRQui
    183 ; CHECK: ********** INTERVALS **********
    184 define void @testLdStConflict() {
    185 entry:
    186   br label %loop
    187 
    188 loop:
    189   %0 = call { <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } @llvm.aarch64.neon.ld4.v2i64.p0i8(i8* null)
    190   %ptr = bitcast i8* undef to <2 x i64>*
    191   store <2 x i64> zeroinitializer, <2 x i64>* %ptr, align 4
    192   %ptr1 = bitcast i8* undef to <2 x i64>*
    193   store <2 x i64> zeroinitializer, <2 x i64>* %ptr1, align 4
    194   %ptr2 = bitcast i8* undef to <2 x i64>*
    195   store <2 x i64> zeroinitializer, <2 x i64>* %ptr2, align 4
    196   %ptr3 = bitcast i8* undef to <2 x i64>*
    197   store <2 x i64> zeroinitializer, <2 x i64>* %ptr3, align 4
    198   %ptr4 = bitcast i8* undef to <2 x i64>*
    199   store <2 x i64> zeroinitializer, <2 x i64>* %ptr4, align 4
    200   br label %loop
    201 }
    202 
    203 declare { <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } @llvm.aarch64.neon.ld4.v2i64.p0i8(i8*)
    204