1 ; Test insertions of i32s into the low half of an i64. 2 ; 3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 4 5 ; Insertion of an i32 can be done using LR. 6 define i64 @f1(i64 %a, i32 %b) { 7 ; CHECK-LABEL: f1: 8 ; CHECK-NOT: {{%r[23]}} 9 ; CHECK: lr %r2, %r3 10 ; CHECK: br %r14 11 %low = zext i32 %b to i64 12 %high = and i64 %a, -4294967296 13 %res = or i64 %high, %low 14 ret i64 %res 15 } 16 17 ; ... and again with the operands reversed. 18 define i64 @f2(i64 %a, i32 %b) { 19 ; CHECK-LABEL: f2: 20 ; CHECK-NOT: {{%r[23]}} 21 ; CHECK: lr %r2, %r3 22 ; CHECK: br %r14 23 %low = zext i32 %b to i64 24 %high = and i64 %a, -4294967296 25 %res = or i64 %low, %high 26 ret i64 %res 27 } 28 29 ; Like f1, but with "in register" zero extension. 30 define i64 @f3(i64 %a, i64 %b) { 31 ; CHECK-LABEL: f3: 32 ; CHECK-NOT: {{%r[23]}} 33 ; CHECK: lr %r2, %r3 34 ; CHECK: br %r14 35 %low = and i64 %b, 4294967295 36 %high = and i64 %a, -4294967296 37 %res = or i64 %high, %low 38 ret i64 %res 39 } 40 41 ; ... and again with the operands reversed. 42 define i64 @f4(i64 %a, i64 %b) { 43 ; CHECK-LABEL: f4: 44 ; CHECK-NOT: {{%r[23]}} 45 ; CHECK: lr %r2, %r3 46 ; CHECK: br %r14 47 %low = and i64 %b, 4294967295 48 %high = and i64 %a, -4294967296 49 %res = or i64 %low, %high 50 ret i64 %res 51 } 52 53 ; Unary operations can be done directly into the low half. 54 define i64 @f5(i64 %a, i32 %b) { 55 ; CHECK-LABEL: f5: 56 ; CHECK-NOT: {{%r[23]}} 57 ; CHECK: lcr %r2, %r3 58 ; CHECK: br %r14 59 %neg = sub i32 0, %b 60 %low = zext i32 %neg to i64 61 %high = and i64 %a, -4294967296 62 %res = or i64 %high, %low 63 ret i64 %res 64 } 65 66 ; ...likewise three-operand binary operations like RLL. 67 define i64 @f6(i64 %a, i32 %b) { 68 ; CHECK-LABEL: f6: 69 ; CHECK-NOT: {{%r[23]}} 70 ; CHECK: rll %r2, %r3, 1 71 ; CHECK: br %r14 72 %parta = shl i32 %b, 1 73 %partb = lshr i32 %b, 31 74 %rot = or i32 %parta, %partb 75 %low = zext i32 %rot to i64 76 %high = and i64 %a, -4294967296 77 %res = or i64 %low, %high 78 ret i64 %res 79 } 80 81 ; Loads can be done directly into the low half. The range of L is checked 82 ; in the move tests. 83 define i64 @f7(i64 %a, i32 *%src) { 84 ; CHECK-LABEL: f7: 85 ; CHECK-NOT: {{%r[23]}} 86 ; CHECK: l %r2, 0(%r3) 87 ; CHECK: br %r14 88 %b = load i32 , i32 *%src 89 %low = zext i32 %b to i64 90 %high = and i64 %a, -4294967296 91 %res = or i64 %high, %low 92 ret i64 %res 93 } 94 95 ; ...likewise extending loads. 96 define i64 @f8(i64 %a, i8 *%src) { 97 ; CHECK-LABEL: f8: 98 ; CHECK-NOT: {{%r[23]}} 99 ; CHECK: lb %r2, 0(%r3) 100 ; CHECK: br %r14 101 %byte = load i8 , i8 *%src 102 %b = sext i8 %byte to i32 103 %low = zext i32 %b to i64 104 %high = and i64 %a, -4294967296 105 %res = or i64 %high, %low 106 ret i64 %res 107 } 108 109 ; Check a case like f1 in which there is no AND. We simply know from context 110 ; that the upper half of one OR operand and the lower half of the other are 111 ; both clear. 112 define i64 @f9(i64 %a, i32 %b) { 113 ; CHECK-LABEL: f9: 114 ; CHECK: sllg %r2, %r2, 32 115 ; CHECK: lr %r2, %r3 116 ; CHECK: br %r14 117 %shift = shl i64 %a, 32 118 %low = zext i32 %b to i64 119 %or = or i64 %shift, %low 120 ret i64 %or 121 } 122 123 ; ...and again with the operands reversed. 124 define i64 @f10(i64 %a, i32 %b) { 125 ; CHECK-LABEL: f10: 126 ; CHECK: sllg %r2, %r2, 32 127 ; CHECK: lr %r2, %r3 128 ; CHECK: br %r14 129 %shift = shl i64 %a, 32 130 %low = zext i32 %b to i64 131 %or = or i64 %low, %shift 132 ret i64 %or 133 } 134 135 ; Like f9, but with "in register" zero extension. 136 define i64 @f11(i64 %a, i64 %b) { 137 ; CHECK-LABEL: f11: 138 ; CHECK: lr %r2, %r3 139 ; CHECK: br %r14 140 %shift = shl i64 %a, 32 141 %low = and i64 %b, 4294967295 142 %or = or i64 %shift, %low 143 ret i64 %or 144 } 145 146 ; ...and again with the operands reversed. 147 define i64 @f12(i64 %a, i64 %b) { 148 ; CHECK-LABEL: f12: 149 ; CHECK: lr %r2, %r3 150 ; CHECK: br %r14 151 %shift = shl i64 %a, 32 152 %low = and i64 %b, 4294967295 153 %or = or i64 %low, %shift 154 ret i64 %or 155 } 156 157 ; Like f9, but for larger shifts than 32. 158 define i64 @f13(i64 %a, i32 %b) { 159 ; CHECK-LABEL: f13: 160 ; CHECK: sllg %r2, %r2, 60 161 ; CHECK: lr %r2, %r3 162 ; CHECK: br %r14 163 %shift = shl i64 %a, 60 164 %low = zext i32 %b to i64 165 %or = or i64 %shift, %low 166 ret i64 %or 167 } 168 169 ; We previously wrongly removed the upper AND as dead. 170 define i64 @f14(i64 %a, i64 %b) { 171 ; CHECK-LABEL: f14: 172 ; CHECK: risbg {{%r[0-5]}}, %r2, 6, 134, 0 173 ; CHECK: br %r14 174 %and1 = and i64 %a, 144115188075855872 175 %and2 = and i64 %b, 15 176 %or = or i64 %and1, %and2 177 %res = icmp eq i64 %or, 0 178 %ext = sext i1 %res to i64 179 ret i64 %ext 180 } 181 182 ; Check another representation of f8. 183 define i64 @f15(i64 %a, i8 *%src) { 184 ; CHECK-LABEL: f15: 185 ; CHECK-NOT: {{%r[23]}} 186 ; CHECK: lb %r2, 0(%r3) 187 ; CHECK: br %r14 188 %byte = load i8 , i8 *%src 189 %b = sext i8 %byte to i64 190 %low = and i64 %b, 4294967295 191 %high = and i64 %a, -4294967296 192 %res = or i64 %high, %low 193 ret i64 %res 194 } 195