1 ; Test 32-bit signed comparison in which the second operand is a variable. 2 ; 3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 4 5 declare i32 @foo() 6 7 ; Check register comparison. 8 define double @f1(double %a, double %b, i32 %i1, i32 %i2) { 9 ; CHECK-LABEL: f1: 10 ; CHECK: crjl %r2, %r3 11 ; CHECK: ldr %f0, %f2 12 ; CHECK: br %r14 13 %cond = icmp slt i32 %i1, %i2 14 %res = select i1 %cond, double %a, double %b 15 ret double %res 16 } 17 18 ; Check the low end of the C range. 19 define double @f2(double %a, double %b, i32 %i1, i32 *%ptr) { 20 ; CHECK-LABEL: f2: 21 ; CHECK: c %r2, 0(%r3) 22 ; CHECK-NEXT: jl 23 ; CHECK: ldr %f0, %f2 24 ; CHECK: br %r14 25 %i2 = load i32 *%ptr 26 %cond = icmp slt i32 %i1, %i2 27 %res = select i1 %cond, double %a, double %b 28 ret double %res 29 } 30 31 ; Check the high end of the aligned C range. 32 define double @f3(double %a, double %b, i32 %i1, i32 *%base) { 33 ; CHECK-LABEL: f3: 34 ; CHECK: c %r2, 4092(%r3) 35 ; CHECK-NEXT: jl 36 ; CHECK: ldr %f0, %f2 37 ; CHECK: br %r14 38 %ptr = getelementptr i32 *%base, i64 1023 39 %i2 = load i32 *%ptr 40 %cond = icmp slt i32 %i1, %i2 41 %res = select i1 %cond, double %a, double %b 42 ret double %res 43 } 44 45 ; Check the next word up, which should use CY instead of C. 46 define double @f4(double %a, double %b, i32 %i1, i32 *%base) { 47 ; CHECK-LABEL: f4: 48 ; CHECK: cy %r2, 4096(%r3) 49 ; CHECK-NEXT: jl 50 ; CHECK: ldr %f0, %f2 51 ; CHECK: br %r14 52 %ptr = getelementptr i32 *%base, i64 1024 53 %i2 = load i32 *%ptr 54 %cond = icmp slt i32 %i1, %i2 55 %res = select i1 %cond, double %a, double %b 56 ret double %res 57 } 58 59 ; Check the high end of the aligned CY range. 60 define double @f5(double %a, double %b, i32 %i1, i32 *%base) { 61 ; CHECK-LABEL: f5: 62 ; CHECK: cy %r2, 524284(%r3) 63 ; CHECK-NEXT: jl 64 ; CHECK: ldr %f0, %f2 65 ; CHECK: br %r14 66 %ptr = getelementptr i32 *%base, i64 131071 67 %i2 = load i32 *%ptr 68 %cond = icmp slt i32 %i1, %i2 69 %res = select i1 %cond, double %a, double %b 70 ret double %res 71 } 72 73 ; Check the next word up, which needs separate address logic. 74 ; Other sequences besides this one would be OK. 75 define double @f6(double %a, double %b, i32 %i1, i32 *%base) { 76 ; CHECK-LABEL: f6: 77 ; CHECK: agfi %r3, 524288 78 ; CHECK: c %r2, 0(%r3) 79 ; CHECK-NEXT: jl 80 ; CHECK: ldr %f0, %f2 81 ; CHECK: br %r14 82 %ptr = getelementptr i32 *%base, i64 131072 83 %i2 = load i32 *%ptr 84 %cond = icmp slt i32 %i1, %i2 85 %res = select i1 %cond, double %a, double %b 86 ret double %res 87 } 88 89 ; Check the high end of the negative aligned CY range. 90 define double @f7(double %a, double %b, i32 %i1, i32 *%base) { 91 ; CHECK-LABEL: f7: 92 ; CHECK: cy %r2, -4(%r3) 93 ; CHECK-NEXT: jl 94 ; CHECK: ldr %f0, %f2 95 ; CHECK: br %r14 96 %ptr = getelementptr i32 *%base, i64 -1 97 %i2 = load i32 *%ptr 98 %cond = icmp slt i32 %i1, %i2 99 %res = select i1 %cond, double %a, double %b 100 ret double %res 101 } 102 103 ; Check the low end of the CY range. 104 define double @f8(double %a, double %b, i32 %i1, i32 *%base) { 105 ; CHECK-LABEL: f8: 106 ; CHECK: cy %r2, -524288(%r3) 107 ; CHECK-NEXT: jl 108 ; CHECK: ldr %f0, %f2 109 ; CHECK: br %r14 110 %ptr = getelementptr i32 *%base, i64 -131072 111 %i2 = load i32 *%ptr 112 %cond = icmp slt i32 %i1, %i2 113 %res = select i1 %cond, double %a, double %b 114 ret double %res 115 } 116 117 ; Check the next word down, which needs separate address logic. 118 ; Other sequences besides this one would be OK. 119 define double @f9(double %a, double %b, i32 %i1, i32 *%base) { 120 ; CHECK-LABEL: f9: 121 ; CHECK: agfi %r3, -524292 122 ; CHECK: c %r2, 0(%r3) 123 ; CHECK-NEXT: jl 124 ; CHECK: ldr %f0, %f2 125 ; CHECK: br %r14 126 %ptr = getelementptr i32 *%base, i64 -131073 127 %i2 = load i32 *%ptr 128 %cond = icmp slt i32 %i1, %i2 129 %res = select i1 %cond, double %a, double %b 130 ret double %res 131 } 132 133 ; Check that C allows an index. 134 define double @f10(double %a, double %b, i32 %i1, i64 %base, i64 %index) { 135 ; CHECK-LABEL: f10: 136 ; CHECK: c %r2, 4092({{%r4,%r3|%r3,%r4}}) 137 ; CHECK-NEXT: jl 138 ; CHECK: ldr %f0, %f2 139 ; CHECK: br %r14 140 %add1 = add i64 %base, %index 141 %add2 = add i64 %add1, 4092 142 %ptr = inttoptr i64 %add2 to i32 * 143 %i2 = load i32 *%ptr 144 %cond = icmp slt i32 %i1, %i2 145 %res = select i1 %cond, double %a, double %b 146 ret double %res 147 } 148 149 ; Check that CY allows an index. 150 define double @f11(double %a, double %b, i32 %i1, i64 %base, i64 %index) { 151 ; CHECK-LABEL: f11: 152 ; CHECK: cy %r2, 4096({{%r4,%r3|%r3,%r4}}) 153 ; CHECK-NEXT: jl 154 ; CHECK: ldr %f0, %f2 155 ; CHECK: br %r14 156 %add1 = add i64 %base, %index 157 %add2 = add i64 %add1, 4096 158 %ptr = inttoptr i64 %add2 to i32 * 159 %i2 = load i32 *%ptr 160 %cond = icmp slt i32 %i1, %i2 161 %res = select i1 %cond, double %a, double %b 162 ret double %res 163 } 164 165 ; The first branch here got recreated by InsertBranch while splitting the 166 ; critical edge %entry->%while.body, which lost the kills information for CC. 167 define void @f12(i32 %a, i32 %b) { 168 ; CHECK-LABEL: f12: 169 ; CHECK: cije %r2, 0 170 ; CHECK: crjlh %r2, 171 ; CHECK: br %r14 172 entry: 173 %cmp11 = icmp eq i32 %a, 0 174 br i1 %cmp11, label %while.end, label %while.body 175 176 while.body: 177 %c = call i32 @foo() 178 %cmp12 = icmp eq i32 %c, %b 179 br i1 %cmp12, label %while.end, label %while.body 180 181 while.end: 182 ret void 183 } 184 185 ; Check the comparison can be reversed if that allows C to be used. 186 define double @f13(double %a, double %b, i32 %i2, i32 *%ptr) { 187 ; CHECK-LABEL: f13: 188 ; CHECK: c %r2, 0(%r3) 189 ; CHECK-NEXT: jh {{\.L.*}} 190 ; CHECK: ldr %f0, %f2 191 ; CHECK: br %r14 192 %i1 = load i32 *%ptr 193 %cond = icmp slt i32 %i1, %i2 194 %res = select i1 %cond, double %a, double %b 195 ret double %res 196 } 197