| Ulrich Weigand | 9e3577f | 2013-05-06 16:17:29 +0000 | [diff] [blame] | 1 | ; Test 32-bit GPR accesses to a PC-relative location. | 
|  | 2 | ; | 
|  | 3 | ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s | 
|  | 4 |  | 
|  | 5 | @gsrc16 = global i16 1 | 
|  | 6 | @gsrc32 = global i32 1 | 
|  | 7 | @gdst16 = global i16 2 | 
|  | 8 | @gdst32 = global i32 2 | 
| Richard Sandiford | 46af5a2 | 2013-05-30 09:45:42 +0000 | [diff] [blame] | 9 | @gsrc16u = global i16 1, align 1, section "foo" | 
|  | 10 | @gsrc32u = global i32 1, align 2, section "foo" | 
|  | 11 | @gdst16u = global i16 2, align 1, section "foo" | 
|  | 12 | @gdst32u = global i32 2, align 2, section "foo" | 
| Richard Sandiford | 54b3691 | 2013-09-27 15:14:04 +0000 | [diff] [blame] | 13 | @garray8 = global [2 x i8] [i8 100, i8 101] | 
|  | 14 | @garray16 = global [2 x i16] [i16 102, i16 103] | 
| Ulrich Weigand | 9e3577f | 2013-05-06 16:17:29 +0000 | [diff] [blame] | 15 |  | 
|  | 16 | ; Check sign-extending loads from i16. | 
|  | 17 | define i32 @f1() { | 
| Stephen Lin | d24ab20 | 2013-07-14 06:24:09 +0000 | [diff] [blame] | 18 | ; CHECK-LABEL: f1: | 
| Ulrich Weigand | 9e3577f | 2013-05-06 16:17:29 +0000 | [diff] [blame] | 19 | ; CHECK: lhrl %r2, gsrc16 | 
|  | 20 | ; CHECK: br %r14 | 
|  | 21 | %val = load i16 *@gsrc16 | 
|  | 22 | %ext = sext i16 %val to i32 | 
|  | 23 | ret i32 %ext | 
|  | 24 | } | 
|  | 25 |  | 
|  | 26 | ; Check zero-extending loads from i16. | 
|  | 27 | define i32 @f2() { | 
| Stephen Lin | d24ab20 | 2013-07-14 06:24:09 +0000 | [diff] [blame] | 28 | ; CHECK-LABEL: f2: | 
| Ulrich Weigand | 9e3577f | 2013-05-06 16:17:29 +0000 | [diff] [blame] | 29 | ; CHECK: llhrl %r2, gsrc16 | 
|  | 30 | ; CHECK: br %r14 | 
|  | 31 | %val = load i16 *@gsrc16 | 
|  | 32 | %ext = zext i16 %val to i32 | 
|  | 33 | ret i32 %ext | 
|  | 34 | } | 
|  | 35 |  | 
|  | 36 | ; Check truncating 16-bit stores. | 
|  | 37 | define void @f3(i32 %val) { | 
| Stephen Lin | d24ab20 | 2013-07-14 06:24:09 +0000 | [diff] [blame] | 38 | ; CHECK-LABEL: f3: | 
| Ulrich Weigand | 9e3577f | 2013-05-06 16:17:29 +0000 | [diff] [blame] | 39 | ; CHECK: sthrl %r2, gdst16 | 
|  | 40 | ; CHECK: br %r14 | 
|  | 41 | %half = trunc i32 %val to i16 | 
|  | 42 | store i16 %half, i16 *@gdst16 | 
|  | 43 | ret void | 
|  | 44 | } | 
|  | 45 |  | 
|  | 46 | ; Check plain loads and stores. | 
|  | 47 | define void @f4() { | 
| Stephen Lin | d24ab20 | 2013-07-14 06:24:09 +0000 | [diff] [blame] | 48 | ; CHECK-LABEL: f4: | 
| Ulrich Weigand | 9e3577f | 2013-05-06 16:17:29 +0000 | [diff] [blame] | 49 | ; CHECK: lrl %r0, gsrc32 | 
|  | 50 | ; CHECK: strl %r0, gdst32 | 
|  | 51 | ; CHECK: br %r14 | 
|  | 52 | %val = load i32 *@gsrc32 | 
|  | 53 | store i32 %val, i32 *@gdst32 | 
|  | 54 | ret void | 
|  | 55 | } | 
| Richard Sandiford | 46af5a2 | 2013-05-30 09:45:42 +0000 | [diff] [blame] | 56 |  | 
|  | 57 | ; Repeat f1 with an unaligned variable. | 
|  | 58 | define i32 @f5() { | 
| Stephen Lin | d24ab20 | 2013-07-14 06:24:09 +0000 | [diff] [blame] | 59 | ; CHECK-LABEL: f5: | 
| Richard Sandiford | 46af5a2 | 2013-05-30 09:45:42 +0000 | [diff] [blame] | 60 | ; CHECK: lgrl [[REG:%r[0-5]]], gsrc16u | 
|  | 61 | ; CHECK: lh %r2, 0([[REG]]) | 
|  | 62 | ; CHECK: br %r14 | 
|  | 63 | %val = load i16 *@gsrc16u, align 1 | 
|  | 64 | %ext = sext i16 %val to i32 | 
|  | 65 | ret i32 %ext | 
|  | 66 | } | 
|  | 67 |  | 
|  | 68 | ; Repeat f2 with an unaligned variable. | 
|  | 69 | define i32 @f6() { | 
| Stephen Lin | d24ab20 | 2013-07-14 06:24:09 +0000 | [diff] [blame] | 70 | ; CHECK-LABEL: f6: | 
| Richard Sandiford | 46af5a2 | 2013-05-30 09:45:42 +0000 | [diff] [blame] | 71 | ; CHECK: lgrl [[REG:%r[0-5]]], gsrc16u | 
|  | 72 | ; CHECK: llh %r2, 0([[REG]]) | 
|  | 73 | ; CHECK: br %r14 | 
|  | 74 | %val = load i16 *@gsrc16u, align 1 | 
|  | 75 | %ext = zext i16 %val to i32 | 
|  | 76 | ret i32 %ext | 
|  | 77 | } | 
|  | 78 |  | 
|  | 79 | ; Repeat f3 with an unaligned variable. | 
|  | 80 | define void @f7(i32 %val) { | 
| Stephen Lin | d24ab20 | 2013-07-14 06:24:09 +0000 | [diff] [blame] | 81 | ; CHECK-LABEL: f7: | 
| Richard Sandiford | 46af5a2 | 2013-05-30 09:45:42 +0000 | [diff] [blame] | 82 | ; CHECK: lgrl [[REG:%r[0-5]]], gdst16u | 
|  | 83 | ; CHECK: sth %r2, 0([[REG]]) | 
|  | 84 | ; CHECK: br %r14 | 
|  | 85 | %half = trunc i32 %val to i16 | 
|  | 86 | store i16 %half, i16 *@gdst16u, align 1 | 
|  | 87 | ret void | 
|  | 88 | } | 
|  | 89 |  | 
|  | 90 | ; Repeat f4 with unaligned variables. | 
|  | 91 | define void @f8() { | 
| Stephen Lin | d24ab20 | 2013-07-14 06:24:09 +0000 | [diff] [blame] | 92 | ; CHECK-LABEL: f8: | 
| Richard Sandiford | 46af5a2 | 2013-05-30 09:45:42 +0000 | [diff] [blame] | 93 | ; CHECK: larl [[REG:%r[0-5]]], gsrc32u | 
|  | 94 | ; CHECK: l [[VAL:%r[0-5]]], 0([[REG]]) | 
|  | 95 | ; CHECK: larl [[REG:%r[0-5]]], gdst32u | 
|  | 96 | ; CHECK: st [[VAL]], 0([[REG]]) | 
|  | 97 | ; CHECK: br %r14 | 
|  | 98 | %val = load i32 *@gsrc32u, align 2 | 
|  | 99 | store i32 %val, i32 *@gdst32u, align 2 | 
|  | 100 | ret void | 
|  | 101 | } | 
| Richard Sandiford | 54b3691 | 2013-09-27 15:14:04 +0000 | [diff] [blame] | 102 |  | 
|  | 103 | ; Test a case where we want to use one LARL for accesses to two different | 
|  | 104 | ; parts of a variable. | 
|  | 105 | define void @f9() { | 
|  | 106 | ; CHECK-LABEL: f9: | 
|  | 107 | ; CHECK: larl [[REG:%r[0-5]]], garray8 | 
|  | 108 | ; CHECK: llc [[VAL:%r[0-5]]], 0([[REG]]) | 
|  | 109 | ; CHECK: srl [[VAL]], 1 | 
|  | 110 | ; CHECK: stc [[VAL]], 1([[REG]]) | 
|  | 111 | ; CHECK: br %r14 | 
|  | 112 | %ptr1 = getelementptr [2 x i8] *@garray8, i64 0, i64 0 | 
|  | 113 | %ptr2 = getelementptr [2 x i8] *@garray8, i64 0, i64 1 | 
|  | 114 | %val = load i8 *%ptr1 | 
|  | 115 | %shr = lshr i8 %val, 1 | 
|  | 116 | store i8 %shr, i8 *%ptr2 | 
|  | 117 | ret void | 
|  | 118 | } | 
|  | 119 |  | 
|  | 120 | ; Test a case where we want to use separate relative-long addresses for | 
|  | 121 | ; two different parts of a variable. | 
|  | 122 | define void @f10() { | 
|  | 123 | ; CHECK-LABEL: f10: | 
|  | 124 | ; CHECK: llhrl [[VAL:%r[0-5]]], garray16 | 
|  | 125 | ; CHECK: srl [[VAL]], 1 | 
|  | 126 | ; CHECK: sthrl [[VAL]], garray16+2 | 
|  | 127 | ; CHECK: br %r14 | 
|  | 128 | %ptr1 = getelementptr [2 x i16] *@garray16, i64 0, i64 0 | 
|  | 129 | %ptr2 = getelementptr [2 x i16] *@garray16, i64 0, i64 1 | 
|  | 130 | %val = load i16 *%ptr1 | 
|  | 131 | %shr = lshr i16 %val, 1 | 
|  | 132 | store i16 %shr, i16 *%ptr2 | 
|  | 133 | ret void | 
|  | 134 | } |