209 lines · plain
1; Test zero extensions from a byte to an i64.2;3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s4 5; Test register extension, starting with an i32.6define i64 @f1(i32 %a) {7; CHECK-LABEL: f1:8; CHECK: llgcr %r2, %r29; CHECK: br %r1410 %byte = trunc i32 %a to i811 %ext = zext i8 %byte to i6412 ret i64 %ext13}14 15; ...and again with an i64.16define i64 @f2(i64 %a) {17; CHECK-LABEL: f2:18; CHECK: llgcr %r2, %r219; CHECK: br %r1420 %byte = trunc i64 %a to i821 %ext = zext i8 %byte to i6422 ret i64 %ext23}24 25; Check ANDs that are equivalent to zero extension.26define i64 @f3(i64 %a) {27; CHECK-LABEL: f3:28; CHECK: llgcr %r2, %r229; CHECK: br %r1430 %ext = and i64 %a, 25531 ret i64 %ext32}33 34; Check LLGC with no displacement.35define i64 @f4(ptr %src) {36; CHECK-LABEL: f4:37; CHECK: llgc %r2, 0(%r2)38; CHECK: br %r1439 %byte = load i8, ptr %src40 %ext = zext i8 %byte to i6441 ret i64 %ext42}43 44; Check the high end of the LLGC range.45define i64 @f5(ptr %src) {46; CHECK-LABEL: f5:47; CHECK: llgc %r2, 524287(%r2)48; CHECK: br %r1449 %ptr = getelementptr i8, ptr %src, i64 52428750 %byte = load i8, ptr %ptr51 %ext = zext i8 %byte to i6452 ret i64 %ext53}54 55; Check the next byte up, which needs separate address logic.56; Other sequences besides this one would be OK.57define i64 @f6(ptr %src) {58; CHECK-LABEL: f6:59; CHECK: agfi %r2, 52428860; CHECK: llgc %r2, 0(%r2)61; CHECK: br %r1462 %ptr = getelementptr i8, ptr %src, i64 52428863 %byte = load i8, ptr %ptr64 %ext = zext i8 %byte to i6465 ret i64 %ext66}67 68; Check the high end of the negative LLGC range.69define i64 @f7(ptr %src) {70; CHECK-LABEL: f7:71; CHECK: llgc %r2, -1(%r2)72; CHECK: br %r1473 %ptr = getelementptr i8, ptr %src, i64 -174 %byte = load i8, ptr %ptr75 %ext = zext i8 %byte to i6476 ret i64 %ext77}78 79; Check the low end of the LLGC range.80define i64 @f8(ptr %src) {81; CHECK-LABEL: f8:82; CHECK: llgc %r2, -524288(%r2)83; CHECK: br %r1484 %ptr = getelementptr i8, ptr %src, i64 -52428885 %byte = load i8, ptr %ptr86 %ext = zext i8 %byte to i6487 ret i64 %ext88}89 90; Check the next byte down, which needs separate address logic.91; Other sequences besides this one would be OK.92define i64 @f9(ptr %src) {93; CHECK-LABEL: f9:94; CHECK: agfi %r2, -52428995; CHECK: llgc %r2, 0(%r2)96; CHECK: br %r1497 %ptr = getelementptr i8, ptr %src, i64 -52428998 %byte = load i8, ptr %ptr99 %ext = zext i8 %byte to i64100 ret i64 %ext101}102 103; Check that LLGC allows an index104define i64 @f10(i64 %src, i64 %index) {105; CHECK-LABEL: f10:106; CHECK: llgc %r2, 524287(%r3,%r2)107; CHECK: br %r14108 %add1 = add i64 %src, %index109 %add2 = add i64 %add1, 524287110 %ptr = inttoptr i64 %add2 to ptr111 %byte = load i8, ptr %ptr112 %ext = zext i8 %byte to i64113 ret i64 %ext114}115 116; Test a case where we spill the source of at least one LLGCR. We want117; to use LLGC if possible.118define void @f11(ptr %ptr) {119; CHECK-LABEL: f11:120; CHECK: llgc {{%r[0-9]+}}, 199(%r15)121; CHECK: br %r14122 %val0 = load volatile i64, ptr %ptr123 %val1 = load volatile i64, ptr %ptr124 %val2 = load volatile i64, ptr %ptr125 %val3 = load volatile i64, ptr %ptr126 %val4 = load volatile i64, ptr %ptr127 %val5 = load volatile i64, ptr %ptr128 %val6 = load volatile i64, ptr %ptr129 %val7 = load volatile i64, ptr %ptr130 %val8 = load volatile i64, ptr %ptr131 %val9 = load volatile i64, ptr %ptr132 %val10 = load volatile i64, ptr %ptr133 %val11 = load volatile i64, ptr %ptr134 %val12 = load volatile i64, ptr %ptr135 %val13 = load volatile i64, ptr %ptr136 %val14 = load volatile i64, ptr %ptr137 %val15 = load volatile i64, ptr %ptr138 139 %trunc0 = trunc i64 %val0 to i8140 %trunc1 = trunc i64 %val1 to i8141 %trunc2 = trunc i64 %val2 to i8142 %trunc3 = trunc i64 %val3 to i8143 %trunc4 = trunc i64 %val4 to i8144 %trunc5 = trunc i64 %val5 to i8145 %trunc6 = trunc i64 %val6 to i8146 %trunc7 = trunc i64 %val7 to i8147 %trunc8 = trunc i64 %val8 to i8148 %trunc9 = trunc i64 %val9 to i8149 %trunc10 = trunc i64 %val10 to i8150 %trunc11 = trunc i64 %val11 to i8151 %trunc12 = trunc i64 %val12 to i8152 %trunc13 = trunc i64 %val13 to i8153 %trunc14 = trunc i64 %val14 to i8154 %trunc15 = trunc i64 %val15 to i8155 156 %ext0 = zext i8 %trunc0 to i64157 %ext1 = zext i8 %trunc1 to i64158 %ext2 = zext i8 %trunc2 to i64159 %ext3 = zext i8 %trunc3 to i64160 %ext4 = zext i8 %trunc4 to i64161 %ext5 = zext i8 %trunc5 to i64162 %ext6 = zext i8 %trunc6 to i64163 %ext7 = zext i8 %trunc7 to i64164 %ext8 = zext i8 %trunc8 to i64165 %ext9 = zext i8 %trunc9 to i64166 %ext10 = zext i8 %trunc10 to i64167 %ext11 = zext i8 %trunc11 to i64168 %ext12 = zext i8 %trunc12 to i64169 %ext13 = zext i8 %trunc13 to i64170 %ext14 = zext i8 %trunc14 to i64171 %ext15 = zext i8 %trunc15 to i64172 173 store volatile i64 %val0, ptr %ptr174 store volatile i64 %val1, ptr %ptr175 store volatile i64 %val2, ptr %ptr176 store volatile i64 %val3, ptr %ptr177 store volatile i64 %val4, ptr %ptr178 store volatile i64 %val5, ptr %ptr179 store volatile i64 %val6, ptr %ptr180 store volatile i64 %val7, ptr %ptr181 store volatile i64 %val8, ptr %ptr182 store volatile i64 %val9, ptr %ptr183 store volatile i64 %val10, ptr %ptr184 store volatile i64 %val11, ptr %ptr185 store volatile i64 %val12, ptr %ptr186 store volatile i64 %val13, ptr %ptr187 store volatile i64 %val14, ptr %ptr188 store volatile i64 %val15, ptr %ptr189 190 store volatile i64 %ext0, ptr %ptr191 store volatile i64 %ext1, ptr %ptr192 store volatile i64 %ext2, ptr %ptr193 store volatile i64 %ext3, ptr %ptr194 store volatile i64 %ext4, ptr %ptr195 store volatile i64 %ext5, ptr %ptr196 store volatile i64 %ext6, ptr %ptr197 store volatile i64 %ext7, ptr %ptr198 store volatile i64 %ext8, ptr %ptr199 store volatile i64 %ext9, ptr %ptr200 store volatile i64 %ext10, ptr %ptr201 store volatile i64 %ext11, ptr %ptr202 store volatile i64 %ext12, ptr %ptr203 store volatile i64 %ext13, ptr %ptr204 store volatile i64 %ext14, ptr %ptr205 store volatile i64 %ext15, ptr %ptr206 207 ret void208}209