1f4a2713aSLionel Sambuc# Test 64-bit COMPARE LOGICAL IMMEDIATE AND BRANCH in cases where the sheer 2f4a2713aSLionel Sambuc# number of instructions causes some branches to be out of range. 3f4a2713aSLionel Sambuc# RUN: python %s | llc -mtriple=s390x-linux-gnu | FileCheck %s 4f4a2713aSLionel Sambuc 5f4a2713aSLionel Sambuc# Construct: 6f4a2713aSLionel Sambuc# 7f4a2713aSLionel Sambuc# before0: 8f4a2713aSLionel Sambuc# conditional branch to after0 9f4a2713aSLionel Sambuc# ... 10f4a2713aSLionel Sambuc# beforeN: 11f4a2713aSLionel Sambuc# conditional branch to after0 12f4a2713aSLionel Sambuc# main: 13f4a2713aSLionel Sambuc# 0xffb4 bytes, from MVIY instructions 14f4a2713aSLionel Sambuc# conditional branch to main 15f4a2713aSLionel Sambuc# after0: 16f4a2713aSLionel Sambuc# ... 17f4a2713aSLionel Sambuc# conditional branch to main 18f4a2713aSLionel Sambuc# afterN: 19f4a2713aSLionel Sambuc# 20f4a2713aSLionel Sambuc# Each conditional branch sequence occupies 18 bytes if it uses a short 21f4a2713aSLionel Sambuc# branch and 24 if it uses a long one. The ones before "main:" have to 22f4a2713aSLionel Sambuc# take the branch length into account, which is 6 for short branches, 23f4a2713aSLionel Sambuc# so the final (0x4c - 6) / 18 == 3 blocks can use short branches. 24f4a2713aSLionel Sambuc# The ones after "main:" do not, so the first 0x4c / 18 == 4 blocks 25f4a2713aSLionel Sambuc# can use short branches. The conservative algorithm we use makes 26f4a2713aSLionel Sambuc# one of the forward branches unnecessarily long, as noted in the 27f4a2713aSLionel Sambuc# check output below. 28f4a2713aSLionel Sambuc# 29f4a2713aSLionel Sambuc# CHECK: lg [[REG:%r[0-5]]], 0(%r3) 30f4a2713aSLionel Sambuc# CHECK: sg [[REG]], 0(%r4) 31f4a2713aSLionel Sambuc# CHECK: clgfi [[REG]], 50 32f4a2713aSLionel Sambuc# CHECK: jgl [[LABEL:\.L[^ ]*]] 33f4a2713aSLionel Sambuc# CHECK: lg [[REG:%r[0-5]]], 0(%r3) 34f4a2713aSLionel Sambuc# CHECK: sg [[REG]], 0(%r4) 35f4a2713aSLionel Sambuc# CHECK: clgfi [[REG]], 51 36f4a2713aSLionel Sambuc# CHECK: jgl [[LABEL]] 37f4a2713aSLionel Sambuc# CHECK: lg [[REG:%r[0-5]]], 0(%r3) 38f4a2713aSLionel Sambuc# CHECK: sg [[REG]], 0(%r4) 39f4a2713aSLionel Sambuc# CHECK: clgfi [[REG]], 52 40f4a2713aSLionel Sambuc# CHECK: jgl [[LABEL]] 41f4a2713aSLionel Sambuc# CHECK: lg [[REG:%r[0-5]]], 0(%r3) 42f4a2713aSLionel Sambuc# CHECK: sg [[REG]], 0(%r4) 43f4a2713aSLionel Sambuc# CHECK: clgfi [[REG]], 53 44f4a2713aSLionel Sambuc# CHECK: jgl [[LABEL]] 45f4a2713aSLionel Sambuc# CHECK: lg [[REG:%r[0-5]]], 0(%r3) 46f4a2713aSLionel Sambuc# CHECK: sg [[REG]], 0(%r4) 47f4a2713aSLionel Sambuc# CHECK: clgfi [[REG]], 54 48f4a2713aSLionel Sambuc# CHECK: jgl [[LABEL]] 49f4a2713aSLionel Sambuc# ...as mentioned above, the next one could be a CLGIJL instead... 50f4a2713aSLionel Sambuc# CHECK: lg [[REG:%r[0-5]]], 0(%r3) 51f4a2713aSLionel Sambuc# CHECK: sg [[REG]], 0(%r4) 52f4a2713aSLionel Sambuc# CHECK: clgfi [[REG]], 55 53f4a2713aSLionel Sambuc# CHECK: jgl [[LABEL]] 54f4a2713aSLionel Sambuc# CHECK: lg [[REG:%r[0-5]]], 0(%r3) 55f4a2713aSLionel Sambuc# CHECK: sg [[REG]], 0(%r4) 56f4a2713aSLionel Sambuc# CHECK: clgijl [[REG]], 56, [[LABEL]] 57f4a2713aSLionel Sambuc# CHECK: lg [[REG:%r[0-5]]], 0(%r3) 58f4a2713aSLionel Sambuc# CHECK: sg [[REG]], 0(%r4) 59f4a2713aSLionel Sambuc# CHECK: clgijl [[REG]], 57, [[LABEL]] 60f4a2713aSLionel Sambuc# ...main goes here... 61f4a2713aSLionel Sambuc# CHECK: lg [[REG:%r[0-5]]], 0(%r3) 62f4a2713aSLionel Sambuc# CHECK: sg [[REG]], 0(%r4) 63f4a2713aSLionel Sambuc# CHECK: clgijl [[REG]], 100, [[LABEL:\.L[^ ]*]] 64f4a2713aSLionel Sambuc# CHECK: lg [[REG:%r[0-5]]], 0(%r3) 65f4a2713aSLionel Sambuc# CHECK: sg [[REG]], 0(%r4) 66f4a2713aSLionel Sambuc# CHECK: clgijl [[REG]], 101, [[LABEL]] 67f4a2713aSLionel Sambuc# CHECK: lg [[REG:%r[0-5]]], 0(%r3) 68f4a2713aSLionel Sambuc# CHECK: sg [[REG]], 0(%r4) 69f4a2713aSLionel Sambuc# CHECK: clgijl [[REG]], 102, [[LABEL]] 70f4a2713aSLionel Sambuc# CHECK: lg [[REG:%r[0-5]]], 0(%r3) 71f4a2713aSLionel Sambuc# CHECK: sg [[REG]], 0(%r4) 72f4a2713aSLionel Sambuc# CHECK: clgijl [[REG]], 103, [[LABEL]] 73f4a2713aSLionel Sambuc# CHECK: lg [[REG:%r[0-5]]], 0(%r3) 74f4a2713aSLionel Sambuc# CHECK: sg [[REG]], 0(%r4) 75f4a2713aSLionel Sambuc# CHECK: clgfi [[REG]], 104 76f4a2713aSLionel Sambuc# CHECK: jgl [[LABEL]] 77f4a2713aSLionel Sambuc# CHECK: lg [[REG:%r[0-5]]], 0(%r3) 78f4a2713aSLionel Sambuc# CHECK: sg [[REG]], 0(%r4) 79f4a2713aSLionel Sambuc# CHECK: clgfi [[REG]], 105 80f4a2713aSLionel Sambuc# CHECK: jgl [[LABEL]] 81f4a2713aSLionel Sambuc# CHECK: lg [[REG:%r[0-5]]], 0(%r3) 82f4a2713aSLionel Sambuc# CHECK: sg [[REG]], 0(%r4) 83f4a2713aSLionel Sambuc# CHECK: clgfi [[REG]], 106 84f4a2713aSLionel Sambuc# CHECK: jgl [[LABEL]] 85f4a2713aSLionel Sambuc# CHECK: lg [[REG:%r[0-5]]], 0(%r3) 86f4a2713aSLionel Sambuc# CHECK: sg [[REG]], 0(%r4) 87f4a2713aSLionel Sambuc# CHECK: clgfi [[REG]], 107 88f4a2713aSLionel Sambuc# CHECK: jgl [[LABEL]] 89f4a2713aSLionel Sambuc 90f4a2713aSLionel Sambucbranch_blocks = 8 91f4a2713aSLionel Sambucmain_size = 0xffb4 92f4a2713aSLionel Sambuc 93f4a2713aSLionel Sambucprint 'define void @f1(i8 *%base, i64 *%stopa, i64 *%stopb) {' 94f4a2713aSLionel Sambucprint 'entry:' 95f4a2713aSLionel Sambucprint ' br label %before0' 96f4a2713aSLionel Sambucprint '' 97f4a2713aSLionel Sambuc 98f4a2713aSLionel Sambucfor i in xrange(branch_blocks): 99f4a2713aSLionel Sambuc next = 'before%d' % (i + 1) if i + 1 < branch_blocks else 'main' 100f4a2713aSLionel Sambuc print 'before%d:' % i 101*0a6a1f1dSLionel Sambuc print ' %%bcur%da = load i64 *%%stopa' % i 102*0a6a1f1dSLionel Sambuc print ' %%bcur%db = load i64 *%%stopb' % i 103f4a2713aSLionel Sambuc print ' %%bsub%d = sub i64 %%bcur%da, %%bcur%db' % (i, i, i) 104f4a2713aSLionel Sambuc print ' %%btest%d = icmp ult i64 %%bsub%d, %d' % (i, i, i + 50) 105f4a2713aSLionel Sambuc print ' br i1 %%btest%d, label %%after0, label %%%s' % (i, next) 106f4a2713aSLionel Sambuc print '' 107f4a2713aSLionel Sambuc 108f4a2713aSLionel Sambucprint '%s:' % next 109f4a2713aSLionel Sambuca, b = 1, 1 110f4a2713aSLionel Sambucfor i in xrange(0, main_size, 6): 111f4a2713aSLionel Sambuc a, b = b, a + b 112f4a2713aSLionel Sambuc offset = 4096 + b % 500000 113f4a2713aSLionel Sambuc value = a % 256 114f4a2713aSLionel Sambuc print ' %%ptr%d = getelementptr i8 *%%base, i64 %d' % (i, offset) 115f4a2713aSLionel Sambuc print ' store volatile i8 %d, i8 *%%ptr%d' % (value, i) 116f4a2713aSLionel Sambuc 117f4a2713aSLionel Sambucfor i in xrange(branch_blocks): 118*0a6a1f1dSLionel Sambuc print ' %%acur%da = load i64 *%%stopa' % i 119*0a6a1f1dSLionel Sambuc print ' %%acur%db = load i64 *%%stopb' % i 120f4a2713aSLionel Sambuc print ' %%asub%d = sub i64 %%acur%da, %%acur%db' % (i, i, i) 121f4a2713aSLionel Sambuc print ' %%atest%d = icmp ult i64 %%asub%d, %d' % (i, i, i + 100) 122f4a2713aSLionel Sambuc print ' br i1 %%atest%d, label %%main, label %%after%d' % (i, i) 123f4a2713aSLionel Sambuc print '' 124f4a2713aSLionel Sambuc print 'after%d:' % i 125f4a2713aSLionel Sambuc 126f4a2713aSLionel Sambucprint ' ret void' 127f4a2713aSLionel Sambucprint '}' 128