1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ 3; RUN: | FileCheck %s -check-prefix=RV32I 4; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \ 5; RUN: | FileCheck %s -check-prefix=RV64I 6 7define i8 @sext_i1_to_i8(i1 %a) nounwind { 8; RV32I-LABEL: sext_i1_to_i8: 9; RV32I: # %bb.0: 10; RV32I-NEXT: andi a0, a0, 1 11; RV32I-NEXT: neg a0, a0 12; RV32I-NEXT: ret 13; 14; RV64I-LABEL: sext_i1_to_i8: 15; RV64I: # %bb.0: 16; RV64I-NEXT: andi a0, a0, 1 17; RV64I-NEXT: neg a0, a0 18; RV64I-NEXT: ret 19 %1 = sext i1 %a to i8 20 ret i8 %1 21} 22 23define i16 @sext_i1_to_i16(i1 %a) nounwind { 24; RV32I-LABEL: sext_i1_to_i16: 25; RV32I: # %bb.0: 26; RV32I-NEXT: andi a0, a0, 1 27; RV32I-NEXT: neg a0, a0 28; RV32I-NEXT: ret 29; 30; RV64I-LABEL: sext_i1_to_i16: 31; RV64I: # %bb.0: 32; RV64I-NEXT: andi a0, a0, 1 33; RV64I-NEXT: neg a0, a0 34; RV64I-NEXT: ret 35 %1 = sext i1 %a to i16 36 ret i16 %1 37} 38 39define i32 @sext_i1_to_i32(i1 %a) nounwind { 40; RV32I-LABEL: sext_i1_to_i32: 41; RV32I: # %bb.0: 42; RV32I-NEXT: andi a0, a0, 1 43; RV32I-NEXT: neg a0, a0 44; RV32I-NEXT: ret 45; 46; RV64I-LABEL: sext_i1_to_i32: 47; RV64I: # %bb.0: 48; RV64I-NEXT: andi a0, a0, 1 49; RV64I-NEXT: neg a0, a0 50; RV64I-NEXT: ret 51 %1 = sext i1 %a to i32 52 ret i32 %1 53} 54 55define i64 @sext_i1_to_i64(i1 %a) nounwind { 56; RV32I-LABEL: sext_i1_to_i64: 57; RV32I: # %bb.0: 58; RV32I-NEXT: andi a0, a0, 1 59; RV32I-NEXT: neg a0, a0 60; RV32I-NEXT: mv a1, a0 61; RV32I-NEXT: ret 62; 63; RV64I-LABEL: sext_i1_to_i64: 64; RV64I: # %bb.0: 65; RV64I-NEXT: andi a0, a0, 1 66; RV64I-NEXT: neg a0, a0 67; RV64I-NEXT: ret 68 %1 = sext i1 %a to i64 69 ret i64 %1 70} 71 72define i16 @sext_i8_to_i16(i8 %a) nounwind { 73; RV32I-LABEL: sext_i8_to_i16: 74; RV32I: # %bb.0: 75; RV32I-NEXT: slli a0, a0, 24 76; RV32I-NEXT: srai a0, a0, 24 77; RV32I-NEXT: ret 78; 79; RV64I-LABEL: sext_i8_to_i16: 80; RV64I: # %bb.0: 81; RV64I-NEXT: slli a0, a0, 56 82; RV64I-NEXT: srai a0, a0, 56 83; RV64I-NEXT: ret 84 %1 = sext i8 %a to i16 85 ret i16 %1 86} 87 88define i32 @sext_i8_to_i32(i8 %a) nounwind { 89; RV32I-LABEL: sext_i8_to_i32: 90; RV32I: # %bb.0: 91; RV32I-NEXT: slli a0, a0, 24 92; RV32I-NEXT: srai a0, a0, 24 93; RV32I-NEXT: ret 94; 95; RV64I-LABEL: sext_i8_to_i32: 96; RV64I: # %bb.0: 97; RV64I-NEXT: slli a0, a0, 56 98; RV64I-NEXT: srai a0, a0, 56 99; RV64I-NEXT: ret 100 %1 = sext i8 %a to i32 101 ret i32 %1 102} 103 104define i64 @sext_i8_to_i64(i8 %a) nounwind { 105; RV32I-LABEL: sext_i8_to_i64: 106; RV32I: # %bb.0: 107; RV32I-NEXT: slli a1, a0, 24 108; RV32I-NEXT: srai a0, a1, 24 109; RV32I-NEXT: srai a1, a1, 31 110; RV32I-NEXT: ret 111; 112; RV64I-LABEL: sext_i8_to_i64: 113; RV64I: # %bb.0: 114; RV64I-NEXT: slli a0, a0, 56 115; RV64I-NEXT: srai a0, a0, 56 116; RV64I-NEXT: ret 117 %1 = sext i8 %a to i64 118 ret i64 %1 119} 120 121define i32 @sext_i16_to_i32(i16 %a) nounwind { 122; RV32I-LABEL: sext_i16_to_i32: 123; RV32I: # %bb.0: 124; RV32I-NEXT: slli a0, a0, 16 125; RV32I-NEXT: srai a0, a0, 16 126; RV32I-NEXT: ret 127; 128; RV64I-LABEL: sext_i16_to_i32: 129; RV64I: # %bb.0: 130; RV64I-NEXT: slli a0, a0, 48 131; RV64I-NEXT: srai a0, a0, 48 132; RV64I-NEXT: ret 133 %1 = sext i16 %a to i32 134 ret i32 %1 135} 136 137define i64 @sext_i16_to_i64(i16 %a) nounwind { 138; RV32I-LABEL: sext_i16_to_i64: 139; RV32I: # %bb.0: 140; RV32I-NEXT: slli a1, a0, 16 141; RV32I-NEXT: srai a0, a1, 16 142; RV32I-NEXT: srai a1, a1, 31 143; RV32I-NEXT: ret 144; 145; RV64I-LABEL: sext_i16_to_i64: 146; RV64I: # %bb.0: 147; RV64I-NEXT: slli a0, a0, 48 148; RV64I-NEXT: srai a0, a0, 48 149; RV64I-NEXT: ret 150 %1 = sext i16 %a to i64 151 ret i64 %1 152} 153 154define i64 @sext_i32_to_i64(i32 %a) nounwind { 155; RV32I-LABEL: sext_i32_to_i64: 156; RV32I: # %bb.0: 157; RV32I-NEXT: srai a1, a0, 31 158; RV32I-NEXT: ret 159; 160; RV64I-LABEL: sext_i32_to_i64: 161; RV64I: # %bb.0: 162; RV64I-NEXT: sext.w a0, a0 163; RV64I-NEXT: ret 164 %1 = sext i32 %a to i64 165 ret i64 %1 166} 167 168define i8 @zext_i1_to_i8(i1 %a) nounwind { 169; RV32I-LABEL: zext_i1_to_i8: 170; RV32I: # %bb.0: 171; RV32I-NEXT: andi a0, a0, 1 172; RV32I-NEXT: ret 173; 174; RV64I-LABEL: zext_i1_to_i8: 175; RV64I: # %bb.0: 176; RV64I-NEXT: andi a0, a0, 1 177; RV64I-NEXT: ret 178 %1 = zext i1 %a to i8 179 ret i8 %1 180} 181 182define i16 @zext_i1_to_i16(i1 %a) nounwind { 183; RV32I-LABEL: zext_i1_to_i16: 184; RV32I: # %bb.0: 185; RV32I-NEXT: andi a0, a0, 1 186; RV32I-NEXT: ret 187; 188; RV64I-LABEL: zext_i1_to_i16: 189; RV64I: # %bb.0: 190; RV64I-NEXT: andi a0, a0, 1 191; RV64I-NEXT: ret 192 %1 = zext i1 %a to i16 193 ret i16 %1 194} 195 196define i32 @zext_i1_to_i32(i1 %a) nounwind { 197; RV32I-LABEL: zext_i1_to_i32: 198; RV32I: # %bb.0: 199; RV32I-NEXT: andi a0, a0, 1 200; RV32I-NEXT: ret 201; 202; RV64I-LABEL: zext_i1_to_i32: 203; RV64I: # %bb.0: 204; RV64I-NEXT: andi a0, a0, 1 205; RV64I-NEXT: ret 206 %1 = zext i1 %a to i32 207 ret i32 %1 208} 209 210define i64 @zext_i1_to_i64(i1 %a) nounwind { 211; RV32I-LABEL: zext_i1_to_i64: 212; RV32I: # %bb.0: 213; RV32I-NEXT: andi a0, a0, 1 214; RV32I-NEXT: mv a1, zero 215; RV32I-NEXT: ret 216; 217; RV64I-LABEL: zext_i1_to_i64: 218; RV64I: # %bb.0: 219; RV64I-NEXT: andi a0, a0, 1 220; RV64I-NEXT: ret 221 %1 = zext i1 %a to i64 222 ret i64 %1 223} 224 225define i16 @zext_i8_to_i16(i8 %a) nounwind { 226; RV32I-LABEL: zext_i8_to_i16: 227; RV32I: # %bb.0: 228; RV32I-NEXT: andi a0, a0, 255 229; RV32I-NEXT: ret 230; 231; RV64I-LABEL: zext_i8_to_i16: 232; RV64I: # %bb.0: 233; RV64I-NEXT: andi a0, a0, 255 234; RV64I-NEXT: ret 235 %1 = zext i8 %a to i16 236 ret i16 %1 237} 238 239define i32 @zext_i8_to_i32(i8 %a) nounwind { 240; RV32I-LABEL: zext_i8_to_i32: 241; RV32I: # %bb.0: 242; RV32I-NEXT: andi a0, a0, 255 243; RV32I-NEXT: ret 244; 245; RV64I-LABEL: zext_i8_to_i32: 246; RV64I: # %bb.0: 247; RV64I-NEXT: andi a0, a0, 255 248; RV64I-NEXT: ret 249 %1 = zext i8 %a to i32 250 ret i32 %1 251} 252 253define i64 @zext_i8_to_i64(i8 %a) nounwind { 254; RV32I-LABEL: zext_i8_to_i64: 255; RV32I: # %bb.0: 256; RV32I-NEXT: andi a0, a0, 255 257; RV32I-NEXT: mv a1, zero 258; RV32I-NEXT: ret 259; 260; RV64I-LABEL: zext_i8_to_i64: 261; RV64I: # %bb.0: 262; RV64I-NEXT: andi a0, a0, 255 263; RV64I-NEXT: ret 264 %1 = zext i8 %a to i64 265 ret i64 %1 266} 267 268define i32 @zext_i16_to_i32(i16 %a) nounwind { 269; RV32I-LABEL: zext_i16_to_i32: 270; RV32I: # %bb.0: 271; RV32I-NEXT: lui a1, 16 272; RV32I-NEXT: addi a1, a1, -1 273; RV32I-NEXT: and a0, a0, a1 274; RV32I-NEXT: ret 275; 276; RV64I-LABEL: zext_i16_to_i32: 277; RV64I: # %bb.0: 278; RV64I-NEXT: lui a1, 16 279; RV64I-NEXT: addiw a1, a1, -1 280; RV64I-NEXT: and a0, a0, a1 281; RV64I-NEXT: ret 282 %1 = zext i16 %a to i32 283 ret i32 %1 284} 285 286define i64 @zext_i16_to_i64(i16 %a) nounwind { 287; RV32I-LABEL: zext_i16_to_i64: 288; RV32I: # %bb.0: 289; RV32I-NEXT: lui a1, 16 290; RV32I-NEXT: addi a1, a1, -1 291; RV32I-NEXT: and a0, a0, a1 292; RV32I-NEXT: mv a1, zero 293; RV32I-NEXT: ret 294; 295; RV64I-LABEL: zext_i16_to_i64: 296; RV64I: # %bb.0: 297; RV64I-NEXT: lui a1, 16 298; RV64I-NEXT: addiw a1, a1, -1 299; RV64I-NEXT: and a0, a0, a1 300; RV64I-NEXT: ret 301 %1 = zext i16 %a to i64 302 ret i64 %1 303} 304 305define i64 @zext_i32_to_i64(i32 %a) nounwind { 306; RV32I-LABEL: zext_i32_to_i64: 307; RV32I: # %bb.0: 308; RV32I-NEXT: mv a1, zero 309; RV32I-NEXT: ret 310; 311; RV64I-LABEL: zext_i32_to_i64: 312; RV64I: # %bb.0: 313; RV64I-NEXT: slli a0, a0, 32 314; RV64I-NEXT: srli a0, a0, 32 315; RV64I-NEXT: ret 316 %1 = zext i32 %a to i64 317 ret i64 %1 318} 319 320define i1 @trunc_i8_to_i1(i8 %a) nounwind { 321; RV32I-LABEL: trunc_i8_to_i1: 322; RV32I: # %bb.0: 323; RV32I-NEXT: ret 324; 325; RV64I-LABEL: trunc_i8_to_i1: 326; RV64I: # %bb.0: 327; RV64I-NEXT: ret 328 %1 = trunc i8 %a to i1 329 ret i1 %1 330} 331 332define i1 @trunc_i16_to_i1(i16 %a) nounwind { 333; RV32I-LABEL: trunc_i16_to_i1: 334; RV32I: # %bb.0: 335; RV32I-NEXT: ret 336; 337; RV64I-LABEL: trunc_i16_to_i1: 338; RV64I: # %bb.0: 339; RV64I-NEXT: ret 340 %1 = trunc i16 %a to i1 341 ret i1 %1 342} 343 344define i1 @trunc_i32_to_i1(i32 %a) nounwind { 345; RV32I-LABEL: trunc_i32_to_i1: 346; RV32I: # %bb.0: 347; RV32I-NEXT: ret 348; 349; RV64I-LABEL: trunc_i32_to_i1: 350; RV64I: # %bb.0: 351; RV64I-NEXT: ret 352 %1 = trunc i32 %a to i1 353 ret i1 %1 354} 355 356define i1 @trunc_i64_to_i1(i64 %a) nounwind { 357; RV32I-LABEL: trunc_i64_to_i1: 358; RV32I: # %bb.0: 359; RV32I-NEXT: ret 360; 361; RV64I-LABEL: trunc_i64_to_i1: 362; RV64I: # %bb.0: 363; RV64I-NEXT: ret 364 %1 = trunc i64 %a to i1 365 ret i1 %1 366} 367 368define i8 @trunc_i16_to_i8(i16 %a) nounwind { 369; RV32I-LABEL: trunc_i16_to_i8: 370; RV32I: # %bb.0: 371; RV32I-NEXT: ret 372; 373; RV64I-LABEL: trunc_i16_to_i8: 374; RV64I: # %bb.0: 375; RV64I-NEXT: ret 376 %1 = trunc i16 %a to i8 377 ret i8 %1 378} 379 380define i8 @trunc_i32_to_i8(i32 %a) nounwind { 381; RV32I-LABEL: trunc_i32_to_i8: 382; RV32I: # %bb.0: 383; RV32I-NEXT: ret 384; 385; RV64I-LABEL: trunc_i32_to_i8: 386; RV64I: # %bb.0: 387; RV64I-NEXT: ret 388 %1 = trunc i32 %a to i8 389 ret i8 %1 390} 391 392define i8 @trunc_i64_to_i8(i64 %a) nounwind { 393; RV32I-LABEL: trunc_i64_to_i8: 394; RV32I: # %bb.0: 395; RV32I-NEXT: ret 396; 397; RV64I-LABEL: trunc_i64_to_i8: 398; RV64I: # %bb.0: 399; RV64I-NEXT: ret 400 %1 = trunc i64 %a to i8 401 ret i8 %1 402} 403 404define i16 @trunc_i32_to_i16(i32 %a) nounwind { 405; RV32I-LABEL: trunc_i32_to_i16: 406; RV32I: # %bb.0: 407; RV32I-NEXT: ret 408; 409; RV64I-LABEL: trunc_i32_to_i16: 410; RV64I: # %bb.0: 411; RV64I-NEXT: ret 412 %1 = trunc i32 %a to i16 413 ret i16 %1 414} 415 416define i16 @trunc_i64_to_i16(i64 %a) nounwind { 417; RV32I-LABEL: trunc_i64_to_i16: 418; RV32I: # %bb.0: 419; RV32I-NEXT: ret 420; 421; RV64I-LABEL: trunc_i64_to_i16: 422; RV64I: # %bb.0: 423; RV64I-NEXT: ret 424 %1 = trunc i64 %a to i16 425 ret i16 %1 426} 427 428define i32 @trunc_i64_to_i32(i64 %a) nounwind { 429; RV32I-LABEL: trunc_i64_to_i32: 430; RV32I: # %bb.0: 431; RV32I-NEXT: ret 432; 433; RV64I-LABEL: trunc_i64_to_i32: 434; RV64I: # %bb.0: 435; RV64I-NEXT: ret 436 %1 = trunc i64 %a to i32 437 ret i32 %1 438} 439 440;; fold (sext (not x)) -> (add (zext x) -1) 441define i32 @sext_of_not_i32(i1 %x) { 442; RV32I-LABEL: sext_of_not_i32: 443; RV32I: # %bb.0: 444; RV32I-NEXT: andi a0, a0, 1 445; RV32I-NEXT: addi a0, a0, -1 446; RV32I-NEXT: ret 447; 448; RV64I-LABEL: sext_of_not_i32: 449; RV64I: # %bb.0: 450; RV64I-NEXT: andi a0, a0, 1 451; RV64I-NEXT: addi a0, a0, -1 452; RV64I-NEXT: ret 453 %xor = xor i1 %x, 1 454 %sext = sext i1 %xor to i32 455 ret i32 %sext 456} 457 458define i64 @sext_of_not_i64(i1 %x) { 459; RV32I-LABEL: sext_of_not_i64: 460; RV32I: # %bb.0: 461; RV32I-NEXT: andi a1, a0, 1 462; RV32I-NEXT: addi a0, a1, -1 463; RV32I-NEXT: sltu a1, a0, a1 464; RV32I-NEXT: addi a1, a1, -1 465; RV32I-NEXT: ret 466; 467; RV64I-LABEL: sext_of_not_i64: 468; RV64I: # %bb.0: 469; RV64I-NEXT: andi a0, a0, 1 470; RV64I-NEXT: addi a0, a0, -1 471; RV64I-NEXT: ret 472 %xor = xor i1 %x, 1 473 %sext = sext i1 %xor to i64 474 ret i64 %sext 475} 476 477;; fold (sext (not (setcc a, b, cc))) -> (sext (setcc a, b, !cc)) 478define i32 @sext_of_not_cmp_i32(i32 %x) { 479; RV32I-LABEL: sext_of_not_cmp_i32: 480; RV32I: # %bb.0: 481; RV32I-NEXT: addi a0, a0, -7 482; RV32I-NEXT: snez a0, a0 483; RV32I-NEXT: neg a0, a0 484; RV32I-NEXT: ret 485; 486; RV64I-LABEL: sext_of_not_cmp_i32: 487; RV64I: # %bb.0: 488; RV64I-NEXT: slli a0, a0, 32 489; RV64I-NEXT: srli a0, a0, 32 490; RV64I-NEXT: addi a0, a0, -7 491; RV64I-NEXT: snez a0, a0 492; RV64I-NEXT: neg a0, a0 493; RV64I-NEXT: ret 494 %cmp = icmp eq i32 %x, 7 495 %xor = xor i1 %cmp, 1 496 %sext = sext i1 %xor to i32 497 ret i32 %sext 498} 499 500define i64 @sext_of_not_cmp_i64(i64 %x) { 501; RV32I-LABEL: sext_of_not_cmp_i64: 502; RV32I: # %bb.0: 503; RV32I-NEXT: xori a0, a0, 7 504; RV32I-NEXT: or a0, a0, a1 505; RV32I-NEXT: snez a0, a0 506; RV32I-NEXT: neg a0, a0 507; RV32I-NEXT: mv a1, a0 508; RV32I-NEXT: ret 509; 510; RV64I-LABEL: sext_of_not_cmp_i64: 511; RV64I: # %bb.0: 512; RV64I-NEXT: addi a0, a0, -7 513; RV64I-NEXT: snez a0, a0 514; RV64I-NEXT: neg a0, a0 515; RV64I-NEXT: ret 516 %cmp = icmp eq i64 %x, 7 517 %xor = xor i1 %cmp, 1 518 %sext = sext i1 %xor to i64 519 ret i64 %sext 520} 521 522;; TODO: fold (add (zext (setcc a, b, cc)), -1) -> (sext (setcc a, b, !cc)) 523define i32 @dec_of_zexted_cmp_i32(i32 %x) { 524; RV32I-LABEL: dec_of_zexted_cmp_i32: 525; RV32I: # %bb.0: 526; RV32I-NEXT: addi a0, a0, -7 527; RV32I-NEXT: seqz a0, a0 528; RV32I-NEXT: addi a0, a0, -1 529; RV32I-NEXT: ret 530; 531; RV64I-LABEL: dec_of_zexted_cmp_i32: 532; RV64I: # %bb.0: 533; RV64I-NEXT: slli a0, a0, 32 534; RV64I-NEXT: srli a0, a0, 32 535; RV64I-NEXT: addi a0, a0, -7 536; RV64I-NEXT: seqz a0, a0 537; RV64I-NEXT: addi a0, a0, -1 538; RV64I-NEXT: ret 539 %cmp = icmp eq i32 %x, 7 540 %zext = zext i1 %cmp to i32 541 %dec = sub i32 %zext, 1 542 ret i32 %dec 543} 544 545define i64 @dec_of_zexted_cmp_i64(i64 %x) { 546; RV32I-LABEL: dec_of_zexted_cmp_i64: 547; RV32I: # %bb.0: 548; RV32I-NEXT: xori a0, a0, 7 549; RV32I-NEXT: or a0, a0, a1 550; RV32I-NEXT: seqz a1, a0 551; RV32I-NEXT: addi a0, a1, -1 552; RV32I-NEXT: sltu a1, a0, a1 553; RV32I-NEXT: addi a1, a1, -1 554; RV32I-NEXT: ret 555; 556; RV64I-LABEL: dec_of_zexted_cmp_i64: 557; RV64I: # %bb.0: 558; RV64I-NEXT: addi a0, a0, -7 559; RV64I-NEXT: seqz a0, a0 560; RV64I-NEXT: addi a0, a0, -1 561; RV64I-NEXT: ret 562 %cmp = icmp eq i64 %x, 7 563 %zext = zext i1 %cmp to i64 564 %dec = sub i64 %zext, 1 565 ret i64 %dec 566} 567