Home | History | Annotate | Download | only in Large
      1 # Test normal conditional branches in cases where the sheer number of
      2 # instructions causes some branches to be out of range.
      3 # RUN: python %s | llc -mtriple=s390x-linux-gnu | FileCheck %s
      4 
      5 # Construct:
      6 #
      7 # before0:
      8 #   conditional branch to after0
      9 #   ...
     10 # beforeN:
     11 #   conditional branch to after0
     12 # main:
     13 #   0xffd8 bytes, from MVIY instructions
     14 #   conditional branch to main
     15 # after0:
     16 #   ...
     17 #   conditional branch to main
     18 # afterN:
     19 #
     20 # Each conditional branch sequence occupies 8 bytes if it uses a short branch
     21 # and 10 if it uses a long one.  The ones before "main:" have to take the branch
     22 # length into account -- which is 4 bytes for short branches -- so the final
     23 # (0x28 - 4) / 8 == 4 blocks can use short branches.  The ones after "main:"
     24 # do not, so the first 0x28 / 8 == 5 can use short branches.  However,
     25 # the conservative algorithm we use makes one branch unnecessarily long
     26 # on each side.
     27 #
     28 # CHECK: c %r4, 0(%r3)
     29 # CHECK: jge [[LABEL:\.L[^ ]*]]
     30 # CHECK: c %r4, 4(%r3)
     31 # CHECK: jge [[LABEL]]
     32 # CHECK: c %r4, 8(%r3)
     33 # CHECK: jge [[LABEL]]
     34 # CHECK: c %r4, 12(%r3)
     35 # CHECK: jge [[LABEL]]
     36 # CHECK: c %r4, 16(%r3)
     37 # CHECK: jge [[LABEL]]
     38 # CHECK: c %r4, 20(%r3)
     39 # CHECK: jge [[LABEL]]
     40 # CHECK: c %r4, 24(%r3)
     41 # CHECK: j{{g?}}e [[LABEL]]
     42 # CHECK: c %r4, 28(%r3)
     43 # CHECK: je [[LABEL]]
     44 # CHECK: c %r4, 32(%r3)
     45 # CHECK: je [[LABEL]]
     46 # CHECK: c %r4, 36(%r3)
     47 # CHECK: je [[LABEL]]
     48 # ...main goes here...
     49 # CHECK: c %r4, 100(%r3)
     50 # CHECK: je [[LABEL:\.L[^ ]*]]
     51 # CHECK: c %r4, 104(%r3)
     52 # CHECK: je [[LABEL]]
     53 # CHECK: c %r4, 108(%r3)
     54 # CHECK: je [[LABEL]]
     55 # CHECK: c %r4, 112(%r3)
     56 # CHECK: je [[LABEL]]
     57 # CHECK: c %r4, 116(%r3)
     58 # CHECK: j{{g?}}e [[LABEL]]
     59 # CHECK: c %r4, 120(%r3)
     60 # CHECK: jge [[LABEL]]
     61 # CHECK: c %r4, 124(%r3)
     62 # CHECK: jge [[LABEL]]
     63 # CHECK: c %r4, 128(%r3)
     64 # CHECK: jge [[LABEL]]
     65 # CHECK: c %r4, 132(%r3)
     66 # CHECK: jge [[LABEL]]
     67 # CHECK: c %r4, 136(%r3)
     68 # CHECK: jge [[LABEL]]
     69 
     70 branch_blocks = 10
     71 main_size = 0xffd8
     72 
     73 print 'define void @f1(i8 *%base, i32 *%stop, i32 %limit) {'
     74 print 'entry:'
     75 print '  br label %before0'
     76 print ''
     77 
     78 for i in xrange(branch_blocks):
     79     next = 'before%d' % (i + 1) if i + 1 < branch_blocks else 'main'
     80     print 'before%d:' % i
     81     print '  %%bstop%d = getelementptr i32, i32 *%%stop, i64 %d' % (i, i)
     82     print '  %%bcur%d = load i32 , i32 *%%bstop%d' % (i, i)
     83     print '  %%btest%d = icmp eq i32 %%limit, %%bcur%d' % (i, i)
     84     print '  br i1 %%btest%d, label %%after0, label %%%s' % (i, next)
     85     print ''
     86 
     87 print '%s:' % next
     88 a, b = 1, 1
     89 for i in xrange(0, main_size, 6):
     90     a, b = b, a + b
     91     offset = 4096 + b % 500000
     92     value = a % 256
     93     print '  %%ptr%d = getelementptr i8, i8 *%%base, i64 %d' % (i, offset)
     94     print '  store volatile i8 %d, i8 *%%ptr%d' % (value, i)
     95 
     96 for i in xrange(branch_blocks):
     97     print '  %%astop%d = getelementptr i32, i32 *%%stop, i64 %d' % (i, i + 25)
     98     print '  %%acur%d = load i32 , i32 *%%astop%d' % (i, i)
     99     print '  %%atest%d = icmp eq i32 %%limit, %%acur%d' % (i, i)
    100     print '  br i1 %%atest%d, label %%main, label %%after%d' % (i, i)
    101     print ''
    102     print 'after%d:' % i
    103 
    104 print '  ret void'
    105 print '}'
    106