1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 2; Test 128-bit arithmetic in vector registers on z13 3; 4; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 | FileCheck %s 5 6; Sign extension from i64. 7define i128 @f1(i64 %a) { 8; CHECK-LABEL: f1: 9; CHECK: # %bb.0: 10; CHECK-NEXT: srag %r0, %r3, 63 11; CHECK-NEXT: vlvgp %v0, %r0, %r3 12; CHECK-NEXT: vst %v0, 0(%r2), 3 13; CHECK-NEXT: br %r14 14 %res = sext i64 %a to i128 15 ret i128 %res 16} 17 18; Sign extension from i64 from memory. 19define i128 @f2(ptr %ptr) { 20; CHECK-LABEL: f2: 21; CHECK: # %bb.0: 22; CHECK-NEXT: vlrepg %v0, 0(%r3) 23; CHECK-NEXT: vrepib %v1, 64 24; CHECK-NEXT: vsrab %v0, %v0, %v1 25; CHECK-NEXT: vst %v0, 0(%r2), 3 26; CHECK-NEXT: br %r14 27 %a = load i64, ptr %ptr 28 %res = sext i64 %a to i128 29 ret i128 %res 30} 31 32; Zero extension from i64. 33define i128 @f3(i64 %a) { 34; CHECK-LABEL: f3: 35; CHECK: # %bb.0: 36; CHECK-NEXT: vgbm %v0, 0 37; CHECK-NEXT: vlvgg %v0, %r3, 1 38; CHECK-NEXT: vst %v0, 0(%r2), 3 39; CHECK-NEXT: br %r14 40 %res = zext i64 %a to i128 41 ret i128 %res 42} 43 44; Zero extension from i64 from memory. 45define i128 @f4(ptr %ptr) { 46; CHECK-LABEL: f4: 47; CHECK: # %bb.0: 48; CHECK-NEXT: vgbm %v0, 0 49; CHECK-NEXT: vleg %v0, 0(%r3), 1 50; CHECK-NEXT: vst %v0, 0(%r2), 3 51; CHECK-NEXT: br %r14 52 %a = load i64, ptr %ptr 53 %res = zext i64 %a to i128 54 ret i128 %res 55} 56 57; Truncation to i64. 58define i64 @f5(i128 %a) { 59; CHECK-LABEL: f5: 60; CHECK: # %bb.0: 61; CHECK-NEXT: vl %v0, 0(%r2), 3 62; CHECK-NEXT: vaq %v0, %v0, %v0 63; CHECK-NEXT: vlgvg %r2, %v0, 1 64; CHECK-NEXT: br %r14 65 %op = add i128 %a, %a 66 %res = trunc i128 %op to i64 67 ret i64 %res 68} 69 70; Truncation to i64 in memory. 71define void @f6(ptr %ptr, i128 %a) { 72; CHECK-LABEL: f6: 73; CHECK: # %bb.0: 74; CHECK-NEXT: vl %v0, 0(%r3), 3 75; CHECK-NEXT: vaq %v0, %v0, %v0 76; CHECK-NEXT: vsteg %v0, 0(%r2), 1 77; CHECK-NEXT: br %r14 78 %op = add i128 %a, %a 79 %res = trunc i128 %op to i64 80 store i64 %res, ptr %ptr 81 ret void 82} 83 84; Sign extension from i32. 85define i128 @f7(i32 %a) { 86; CHECK-LABEL: f7: 87; CHECK: # %bb.0: 88; CHECK-NEXT: lgfr %r0, %r3 89; CHECK-NEXT: srag %r1, %r0, 63 90; CHECK-NEXT: vlvgp %v0, %r1, %r0 91; CHECK-NEXT: vst %v0, 0(%r2), 3 92; CHECK-NEXT: br %r14 93 %res = sext i32 %a to i128 94 ret i128 %res 95} 96 97; Sign extension from i32 from memory. 98define i128 @f8(ptr %ptr) { 99; CHECK-LABEL: f8: 100; CHECK: # %bb.0: 101; CHECK-NEXT: vlrepf %v0, 0(%r3) 102; CHECK-NEXT: vrepib %v1, 96 103; CHECK-NEXT: vsrab %v0, %v0, %v1 104; CHECK-NEXT: vst %v0, 0(%r2), 3 105; CHECK-NEXT: br %r14 106 %a = load i32, ptr %ptr 107 %res = sext i32 %a to i128 108 ret i128 %res 109} 110 111; Zero extension from i32. 112define i128 @f9(i32 %a) { 113; CHECK-LABEL: f9: 114; CHECK: # %bb.0: 115; CHECK-NEXT: vgbm %v0, 0 116; CHECK-NEXT: vlvgf %v0, %r3, 3 117; CHECK-NEXT: vst %v0, 0(%r2), 3 118; CHECK-NEXT: br %r14 119 %res = zext i32 %a to i128 120 ret i128 %res 121} 122 123; Zero extension from i32 from memory. 124define i128 @f10(ptr %ptr) { 125; CHECK-LABEL: f10: 126; CHECK: # %bb.0: 127; CHECK-NEXT: vgbm %v0, 0 128; CHECK-NEXT: vlef %v0, 0(%r3), 3 129; CHECK-NEXT: vst %v0, 0(%r2), 3 130; CHECK-NEXT: br %r14 131 %a = load i32, ptr %ptr 132 %res = zext i32 %a to i128 133 ret i128 %res 134} 135 136; Truncation to i32. 137define i32 @f11(i128 %a) { 138; CHECK-LABEL: f11: 139; CHECK: # %bb.0: 140; CHECK-NEXT: vl %v0, 0(%r2), 3 141; CHECK-NEXT: vaq %v0, %v0, %v0 142; CHECK-NEXT: vlgvf %r2, %v0, 3 143; CHECK-NEXT: # kill: def $r2l killed $r2l killed $r2d 144; CHECK-NEXT: br %r14 145 %op = add i128 %a, %a 146 %res = trunc i128 %op to i32 147 ret i32 %res 148} 149 150; Truncation to i32 in memory. 151define void @f12(ptr %ptr, i128 %a) { 152; CHECK-LABEL: f12: 153; CHECK: # %bb.0: 154; CHECK-NEXT: vl %v0, 0(%r3), 3 155; CHECK-NEXT: vaq %v0, %v0, %v0 156; CHECK-NEXT: vstef %v0, 0(%r2), 3 157; CHECK-NEXT: br %r14 158 %op = add i128 %a, %a 159 %res = trunc i128 %op to i32 160 store i32 %res, ptr %ptr 161 ret void 162} 163 164; Sign extension from i16. 165define i128 @f13(i16 %a) { 166; CHECK-LABEL: f13: 167; CHECK: # %bb.0: 168; CHECK-NEXT: # kill: def $r3l killed $r3l def $r3d 169; CHECK-NEXT: lghr %r0, %r3 170; CHECK-NEXT: srag %r1, %r0, 63 171; CHECK-NEXT: vlvgp %v0, %r1, %r0 172; CHECK-NEXT: vst %v0, 0(%r2), 3 173; CHECK-NEXT: br %r14 174 %res = sext i16 %a to i128 175 ret i128 %res 176} 177 178; Sign extension from i16 from memory. 179define i128 @f14(ptr %ptr) { 180; CHECK-LABEL: f14: 181; CHECK: # %bb.0: 182; CHECK-NEXT: vlreph %v0, 0(%r3) 183; CHECK-NEXT: vrepib %v1, 112 184; CHECK-NEXT: vsrab %v0, %v0, %v1 185; CHECK-NEXT: vst %v0, 0(%r2), 3 186; CHECK-NEXT: br %r14 187 %a = load i16, ptr %ptr 188 %res = sext i16 %a to i128 189 ret i128 %res 190} 191 192; Zero extension from i16. 193define i128 @f15(i16 %a) { 194; CHECK-LABEL: f15: 195; CHECK: # %bb.0: 196; CHECK-NEXT: vgbm %v0, 0 197; CHECK-NEXT: vlvgh %v0, %r3, 7 198; CHECK-NEXT: vst %v0, 0(%r2), 3 199; CHECK-NEXT: br %r14 200 %res = zext i16 %a to i128 201 ret i128 %res 202} 203 204; Zero extension from i16 from memory. 205define i128 @f16(ptr %ptr) { 206; CHECK-LABEL: f16: 207; CHECK: # %bb.0: 208; CHECK-NEXT: vgbm %v0, 0 209; CHECK-NEXT: vleh %v0, 0(%r3), 7 210; CHECK-NEXT: vst %v0, 0(%r2), 3 211; CHECK-NEXT: br %r14 212 %a = load i16, ptr %ptr 213 %res = zext i16 %a to i128 214 ret i128 %res 215} 216 217; Truncation to i16. 218define i16 @f17(i128 %a) { 219; CHECK-LABEL: f17: 220; CHECK: # %bb.0: 221; CHECK-NEXT: vl %v0, 0(%r2), 3 222; CHECK-NEXT: vaq %v0, %v0, %v0 223; CHECK-NEXT: vlgvf %r2, %v0, 3 224; CHECK-NEXT: # kill: def $r2l killed $r2l killed $r2d 225; CHECK-NEXT: br %r14 226 %op = add i128 %a, %a 227 %res = trunc i128 %op to i16 228 ret i16 %res 229} 230 231; Truncation to i16 in memory. 232define void @f18(ptr %ptr, i128 %a) { 233; CHECK-LABEL: f18: 234; CHECK: # %bb.0: 235; CHECK-NEXT: vl %v0, 0(%r3), 3 236; CHECK-NEXT: vaq %v0, %v0, %v0 237; CHECK-NEXT: vsteh %v0, 0(%r2), 7 238; CHECK-NEXT: br %r14 239 %op = add i128 %a, %a 240 %res = trunc i128 %op to i16 241 store i16 %res, ptr %ptr 242 ret void 243} 244 245; Sign extension from i8. 246define i128 @f19(i8 %a) { 247; CHECK-LABEL: f19: 248; CHECK: # %bb.0: 249; CHECK-NEXT: # kill: def $r3l killed $r3l def $r3d 250; CHECK-NEXT: lgbr %r0, %r3 251; CHECK-NEXT: srag %r1, %r0, 63 252; CHECK-NEXT: vlvgp %v0, %r1, %r0 253; CHECK-NEXT: vst %v0, 0(%r2), 3 254; CHECK-NEXT: br %r14 255 %res = sext i8 %a to i128 256 ret i128 %res 257} 258 259; Sign extension from i8 from memory. 260define i128 @f20(ptr %ptr) { 261; CHECK-LABEL: f20: 262; CHECK: # %bb.0: 263; CHECK-NEXT: vlrepb %v0, 0(%r3) 264; CHECK-NEXT: vrepib %v1, 120 265; CHECK-NEXT: vsrab %v0, %v0, %v1 266; CHECK-NEXT: vst %v0, 0(%r2), 3 267; CHECK-NEXT: br %r14 268 %a = load i8, ptr %ptr 269 %res = sext i8 %a to i128 270 ret i128 %res 271} 272 273; Zero extension from i8. 274define i128 @f21(i8 %a) { 275; CHECK-LABEL: f21: 276; CHECK: # %bb.0: 277; CHECK-NEXT: vgbm %v0, 0 278; CHECK-NEXT: vlvgb %v0, %r3, 15 279; CHECK-NEXT: vst %v0, 0(%r2), 3 280; CHECK-NEXT: br %r14 281 %res = zext i8 %a to i128 282 ret i128 %res 283} 284 285; Zero extension from i8 from memory. 286define i128 @f22(ptr %ptr) { 287; CHECK-LABEL: f22: 288; CHECK: # %bb.0: 289; CHECK-NEXT: vgbm %v0, 0 290; CHECK-NEXT: vleb %v0, 0(%r3), 15 291; CHECK-NEXT: vst %v0, 0(%r2), 3 292; CHECK-NEXT: br %r14 293 %a = load i8, ptr %ptr 294 %res = zext i8 %a to i128 295 ret i128 %res 296} 297 298; Truncation to i8. 299define i8 @f23(i128 %a) { 300; CHECK-LABEL: f23: 301; CHECK: # %bb.0: 302; CHECK-NEXT: vl %v0, 0(%r2), 3 303; CHECK-NEXT: vaq %v0, %v0, %v0 304; CHECK-NEXT: vlgvf %r2, %v0, 3 305; CHECK-NEXT: # kill: def $r2l killed $r2l killed $r2d 306; CHECK-NEXT: br %r14 307 %op = add i128 %a, %a 308 %res = trunc i128 %op to i8 309 ret i8 %res 310} 311 312; Truncation to i8 in memory. 313define void @f24(ptr %ptr, i128 %a) { 314; CHECK-LABEL: f24: 315; CHECK: # %bb.0: 316; CHECK-NEXT: vl %v0, 0(%r3), 3 317; CHECK-NEXT: vaq %v0, %v0, %v0 318; CHECK-NEXT: vsteb %v0, 0(%r2), 15 319; CHECK-NEXT: br %r14 320 %op = add i128 %a, %a 321 %res = trunc i128 %op to i8 322 store i8 %res, ptr %ptr 323 ret void 324} 325 326; Sign extension from i1. 327define i128 @f25(i1 %a) { 328; CHECK-LABEL: f25: 329; CHECK: # %bb.0: 330; CHECK-NEXT: larl %r1, .LCPI24_0 331; CHECK-NEXT: vl %v1, 0(%r1), 3 332; CHECK-NEXT: vlvgp %v0, %r3, %r3 333; CHECK-NEXT: vn %v0, %v0, %v1 334; CHECK-NEXT: vgbm %v1, 0 335; CHECK-NEXT: vsq %v0, %v1, %v0 336; CHECK-NEXT: vst %v0, 0(%r2), 3 337; CHECK-NEXT: br %r14 338 %res = sext i1 %a to i128 339 ret i128 %res 340} 341 342; Sign extension from i1 from memory. 343define i128 @f26(ptr %ptr) { 344; CHECK-LABEL: f26: 345; CHECK: # %bb.0: 346; CHECK-NEXT: vgbm %v1, 0 347; CHECK-NEXT: vleb %v1, 0(%r3), 15 348; CHECK-NEXT: larl %r1, .LCPI25_0 349; CHECK-NEXT: vl %v2, 0(%r1), 3 350; CHECK-NEXT: vgbm %v0, 0 351; CHECK-NEXT: vn %v1, %v1, %v2 352; CHECK-NEXT: vsq %v0, %v0, %v1 353; CHECK-NEXT: vst %v0, 0(%r2), 3 354; CHECK-NEXT: br %r14 355 %a = load i1, ptr %ptr 356 %res = sext i1 %a to i128 357 ret i128 %res 358} 359 360; Zero extension from i1. 361define i128 @f27(i1 %a) { 362; CHECK-LABEL: f27: 363; CHECK: # %bb.0: 364; CHECK-NEXT: larl %r1, .LCPI26_0 365; CHECK-NEXT: vl %v1, 0(%r1), 3 366; CHECK-NEXT: vlvgp %v0, %r3, %r3 367; CHECK-NEXT: vn %v0, %v0, %v1 368; CHECK-NEXT: vst %v0, 0(%r2), 3 369; CHECK-NEXT: br %r14 370 %res = zext i1 %a to i128 371 ret i128 %res 372} 373 374; Zero extension from i1 from memory. 375define i128 @f28(ptr %ptr) { 376; CHECK-LABEL: f28: 377; CHECK: # %bb.0: 378; CHECK-NEXT: vgbm %v0, 0 379; CHECK-NEXT: vleb %v0, 0(%r3), 15 380; CHECK-NEXT: vst %v0, 0(%r2), 3 381; CHECK-NEXT: br %r14 382 %a = load i1, ptr %ptr 383 %res = zext i1 %a to i128 384 ret i128 %res 385} 386 387; Truncation to i1. 388define i1 @f29(i128 %a) { 389; CHECK-LABEL: f29: 390; CHECK: # %bb.0: 391; CHECK-NEXT: vl %v0, 0(%r2), 3 392; CHECK-NEXT: vaq %v0, %v0, %v0 393; CHECK-NEXT: vlgvf %r2, %v0, 3 394; CHECK-NEXT: # kill: def $r2l killed $r2l killed $r2d 395; CHECK-NEXT: br %r14 396 %op = add i128 %a, %a 397 %res = trunc i128 %op to i1 398 ret i1 %res 399} 400 401; Truncation to i1 in memory. 402define void @f30(ptr %ptr, i128 %a) { 403; CHECK-LABEL: f30: 404; CHECK: # %bb.0: 405; CHECK-NEXT: vl %v0, 0(%r3), 3 406; CHECK-NEXT: larl %r1, .LCPI29_0 407; CHECK-NEXT: vl %v1, 0(%r1), 3 408; CHECK-NEXT: vaq %v0, %v0, %v0 409; CHECK-NEXT: vn %v0, %v0, %v1 410; CHECK-NEXT: vsteb %v0, 0(%r2), 15 411; CHECK-NEXT: br %r14 412 %op = add i128 %a, %a 413 %res = trunc i128 %op to i1 414 store i1 %res, ptr %ptr 415 ret void 416} 417