1; Test the use of TEST UNDER MASK for 64-bit operations. 2; 3; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s 4; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s 5 6@g = global i32 0 7 8; Check the lowest useful TMLL value. 9define void @f1(i64 %a) { 10; CHECK-LABEL: f1: 11; CHECK: tmll %r2, 1 12; CHECK: ber %r14 13; CHECK: br %r14 14entry: 15 %and = and i64 %a, 1 16 %cmp = icmp eq i64 %and, 0 17 br i1 %cmp, label %exit, label %store 18 19store: 20 store i32 1, i32 *@g 21 br label %exit 22 23exit: 24 ret void 25} 26 27; Check the high end of the TMLL range. 28define void @f2(i64 %a) { 29; CHECK-LABEL: f2: 30; CHECK: tmll %r2, 65535 31; CHECK: bner %r14 32; CHECK: br %r14 33entry: 34 %and = and i64 %a, 65535 35 %cmp = icmp ne i64 %and, 0 36 br i1 %cmp, label %exit, label %store 37 38store: 39 store i32 1, i32 *@g 40 br label %exit 41 42exit: 43 ret void 44} 45 46; Check the lowest useful TMLH value, which is the next value up. 47define void @f3(i64 %a) { 48; CHECK-LABEL: f3: 49; CHECK: tmlh %r2, 1 50; CHECK: bner %r14 51; CHECK: br %r14 52entry: 53 %and = and i64 %a, 65536 54 %cmp = icmp ne i64 %and, 0 55 br i1 %cmp, label %exit, label %store 56 57store: 58 store i32 1, i32 *@g 59 br label %exit 60 61exit: 62 ret void 63} 64 65; Check the next value up again, which cannot use TM. 66define void @f4(i64 %a) { 67; CHECK-LABEL: f4: 68; CHECK-NOT: {{tm[lh].}} 69; CHECK: br %r14 70entry: 71 %and = and i64 %a, 4294901759 72 %cmp = icmp eq i64 %and, 0 73 br i1 %cmp, label %exit, label %store 74 75store: 76 store i32 1, i32 *@g 77 br label %exit 78 79exit: 80 ret void 81} 82 83; Check the high end of the TMLH range. 84define void @f5(i64 %a) { 85; CHECK-LABEL: f5: 86; CHECK: tmlh %r2, 65535 87; CHECK: ber %r14 88; CHECK: br %r14 89entry: 90 %and = and i64 %a, 4294901760 91 %cmp = icmp eq i64 %and, 0 92 br i1 %cmp, label %exit, label %store 93 94store: 95 store i32 1, i32 *@g 96 br label %exit 97 98exit: 99 ret void 100} 101 102; Check the lowest useful TMHL value. 103define void @f6(i64 %a) { 104; CHECK-LABEL: f6: 105; CHECK: tmhl %r2, 1 106; CHECK: ber %r14 107; CHECK: br %r14 108entry: 109 %and = and i64 %a, 4294967296 110 %cmp = icmp eq i64 %and, 0 111 br i1 %cmp, label %exit, label %store 112 113store: 114 store i32 1, i32 *@g 115 br label %exit 116 117exit: 118 ret void 119} 120 121; Check the next value up again, which cannot use TM. 122define void @f7(i64 %a) { 123; CHECK-LABEL: f7: 124; CHECK-NOT: {{tm[lh].}} 125; CHECK: br %r14 126entry: 127 %and = and i64 %a, 4294967297 128 %cmp = icmp ne i64 %and, 0 129 br i1 %cmp, label %exit, label %store 130 131store: 132 store i32 1, i32 *@g 133 br label %exit 134 135exit: 136 ret void 137} 138 139; Check the high end of the TMHL range. 140define void @f8(i64 %a) { 141; CHECK-LABEL: f8: 142; CHECK: tmhl %r2, 65535 143; CHECK: bner %r14 144; CHECK: br %r14 145entry: 146 %and = and i64 %a, 281470681743360 147 %cmp = icmp ne i64 %and, 0 148 br i1 %cmp, label %exit, label %store 149 150store: 151 store i32 1, i32 *@g 152 br label %exit 153 154exit: 155 ret void 156} 157 158; Check the lowest useful TMHH value. 159define void @f9(i64 %a) { 160; CHECK-LABEL: f9: 161; CHECK: tmhh %r2, 1 162; CHECK: bner %r14 163; CHECK: br %r14 164entry: 165 %and = and i64 %a, 281474976710656 166 %cmp = icmp ne i64 %and, 0 167 br i1 %cmp, label %exit, label %store 168 169store: 170 store i32 1, i32 *@g 171 br label %exit 172 173exit: 174 ret void 175} 176 177; Check the high end of the TMHH range. 178define void @f10(i64 %a) { 179; CHECK-LABEL: f10: 180; CHECK: tmhh %r2, 65535 181; CHECK: ber %r14 182; CHECK: br %r14 183entry: 184 %and = and i64 %a, 18446462598732840960 185 %cmp = icmp eq i64 %and, 0 186 br i1 %cmp, label %exit, label %store 187 188store: 189 store i32 1, i32 *@g 190 br label %exit 191 192exit: 193 ret void 194} 195 196; Check that we can fold an SHL into a TMxx mask. 197define void @f11(i64 %a) { 198; CHECK-LABEL: f11: 199; CHECK: tmhl %r2, 32768 200; CHECK: bner %r14 201; CHECK: br %r14 202entry: 203 %shl = shl i64 %a, 1 204 %and = and i64 %shl, 281474976710656 205 %cmp = icmp ne i64 %and, 0 206 br i1 %cmp, label %exit, label %store 207 208store: 209 store i32 1, i32 *@g 210 br label %exit 211 212exit: 213 ret void 214} 215 216; Check that we can fold an SHR into a TMxx mask. 217define void @f12(i64 %a) { 218; CHECK-LABEL: f12: 219; CHECK: tmhh %r2, 256 220; CHECK: bner %r14 221; CHECK: br %r14 222entry: 223 %shr = lshr i64 %a, 56 224 %and = and i64 %shr, 1 225 %cmp = icmp ne i64 %and, 0 226 br i1 %cmp, label %exit, label %store 227 228store: 229 store i32 1, i32 *@g 230 br label %exit 231 232exit: 233 ret void 234} 235 236; Check a case where TMHH can be used to implement a ult comparison. 237define void @f13(i64 %a) { 238; CHECK-LABEL: f13: 239; CHECK: tmhh %r2, 49152 240; CHECK: bnor %r14 241; CHECK: br %r14 242entry: 243 %cmp = icmp ult i64 %a, 13835058055282163712 244 br i1 %cmp, label %exit, label %store 245 246store: 247 store i32 1, i32 *@g 248 br label %exit 249 250exit: 251 ret void 252} 253 254; And again with ule. 255define void @f14(i64 %a) { 256; CHECK-LABEL: f14: 257; CHECK: tmhh %r2, 49152 258; CHECK: bnor %r14 259; CHECK: br %r14 260entry: 261 %cmp = icmp ule i64 %a, 13835058055282163711 262 br i1 %cmp, label %exit, label %store 263 264store: 265 store i32 1, i32 *@g 266 br label %exit 267 268exit: 269 ret void 270} 271 272; And again with ugt. 273define void @f15(i64 %a) { 274; CHECK-LABEL: f15: 275; CHECK: tmhh %r2, 49152 276; CHECK: bor %r14 277; CHECK: br %r14 278entry: 279 %cmp = icmp ugt i64 %a, 13835058055282163711 280 br i1 %cmp, label %exit, label %store 281 282store: 283 store i32 1, i32 *@g 284 br label %exit 285 286exit: 287 ret void 288} 289 290; And again with uge. 291define void @f16(i64 %a) { 292; CHECK-LABEL: f16: 293; CHECK: tmhh %r2, 49152 294; CHECK: bor %r14 295; CHECK: br %r14 296entry: 297 %cmp = icmp uge i64 %a, 13835058055282163712 298 br i1 %cmp, label %exit, label %store 299 300store: 301 store i32 1, i32 *@g 302 br label %exit 303 304exit: 305 ret void 306} 307 308; Decrease the constant from f13 to make TMHH invalid. 309define void @f17(i64 %a) { 310; CHECK-LABEL: f17: 311; CHECK-NOT: tmhh 312; CHECK: srlg [[REG:%r[0-5]]], %r2, 48 313; CHECK: cgfi [[REG]], 49151 314; CHECK-NOT: tmhh 315; CHECK: br %r14 316entry: 317 %cmp = icmp ult i64 %a, 13834776580305453056 318 br i1 %cmp, label %exit, label %store 319 320store: 321 store i32 1, i32 *@g 322 br label %exit 323 324exit: 325 ret void 326} 327 328; Check that we don't use TMHH just to test the top bit. 329define void @f18(i64 %a) { 330; CHECK-LABEL: f18: 331; CHECK-NOT: tmhh 332; CHECK: cgibhe %r2, 0, 0(%r14) 333; CHECK: br %r14 334entry: 335 %cmp = icmp ult i64 %a, 9223372036854775808 336 br i1 %cmp, label %exit, label %store 337 338store: 339 store i32 1, i32 *@g 340 br label %exit 341 342exit: 343 ret void 344} 345 346; Check that we don't fold a shift if the comparison value 347; would need to be shifted out of range 348define void @f19(i64 %a) { 349; CHECK-LABEL: f19: 350; CHECK-NOT: tmhh 351; CHECK: srlg [[REG:%r[0-5]]], %r2, 63 352; CHECK: cgibl [[REG]], 3, 0(%r14) 353; CHECK: br %r14 354entry: 355 %shr = lshr i64 %a, 63 356 %cmp = icmp ult i64 %shr, 3 357 br i1 %cmp, label %exit, label %store 358 359store: 360 store i32 1, i32 *@g 361 br label %exit 362 363exit: 364 ret void 365} 366 367