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=riscv32 -mattr=+zbb -verify-machineinstrs < %s \ 5; RUN: | FileCheck %s --check-prefix=RV32ZBB 6; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbt -verify-machineinstrs < %s \ 7; RUN: | FileCheck %s --check-prefix=RV32ZBT 8; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \ 9; RUN: | FileCheck %s --check-prefix=RV64I 10; RUN: llc -mtriple=riscv64 -mattr=+zbb -verify-machineinstrs < %s \ 11; RUN: | FileCheck %s --check-prefix=RV64ZBB 12; RUN: llc -mtriple=riscv64 -mattr=+experimental-zbt -verify-machineinstrs < %s \ 13; RUN: | FileCheck %s --check-prefix=RV64ZBT 14 15declare i8 @llvm.abs.i8(i8, i1 immarg) 16declare i16 @llvm.abs.i16(i16, i1 immarg) 17declare i32 @llvm.abs.i32(i32, i1 immarg) 18declare i64 @llvm.abs.i64(i64, i1 immarg) 19declare i128 @llvm.abs.i128(i128, i1 immarg) 20 21define i8 @abs8(i8 %x) { 22; RV32I-LABEL: abs8: 23; RV32I: # %bb.0: 24; RV32I-NEXT: slli a1, a0, 24 25; RV32I-NEXT: srai a1, a1, 31 26; RV32I-NEXT: xor a0, a0, a1 27; RV32I-NEXT: sub a0, a0, a1 28; RV32I-NEXT: ret 29; 30; RV32ZBB-LABEL: abs8: 31; RV32ZBB: # %bb.0: 32; RV32ZBB-NEXT: sext.b a0, a0 33; RV32ZBB-NEXT: neg a1, a0 34; RV32ZBB-NEXT: max a0, a0, a1 35; RV32ZBB-NEXT: ret 36; 37; RV32ZBT-LABEL: abs8: 38; RV32ZBT: # %bb.0: 39; RV32ZBT-NEXT: slli a1, a0, 24 40; RV32ZBT-NEXT: srai a1, a1, 31 41; RV32ZBT-NEXT: xor a0, a0, a1 42; RV32ZBT-NEXT: sub a0, a0, a1 43; RV32ZBT-NEXT: ret 44; 45; RV64I-LABEL: abs8: 46; RV64I: # %bb.0: 47; RV64I-NEXT: slli a1, a0, 56 48; RV64I-NEXT: srai a1, a1, 63 49; RV64I-NEXT: xor a0, a0, a1 50; RV64I-NEXT: sub a0, a0, a1 51; RV64I-NEXT: ret 52; 53; RV64ZBB-LABEL: abs8: 54; RV64ZBB: # %bb.0: 55; RV64ZBB-NEXT: sext.b a0, a0 56; RV64ZBB-NEXT: neg a1, a0 57; RV64ZBB-NEXT: max a0, a0, a1 58; RV64ZBB-NEXT: ret 59; 60; RV64ZBT-LABEL: abs8: 61; RV64ZBT: # %bb.0: 62; RV64ZBT-NEXT: slli a1, a0, 56 63; RV64ZBT-NEXT: srai a1, a1, 63 64; RV64ZBT-NEXT: xor a0, a0, a1 65; RV64ZBT-NEXT: sub a0, a0, a1 66; RV64ZBT-NEXT: ret 67 %abs = tail call i8 @llvm.abs.i8(i8 %x, i1 true) 68 ret i8 %abs 69} 70 71define i8 @select_abs8(i8 %x) { 72; RV32I-LABEL: select_abs8: 73; RV32I: # %bb.0: 74; RV32I-NEXT: slli a1, a0, 24 75; RV32I-NEXT: srai a1, a1, 31 76; RV32I-NEXT: xor a0, a0, a1 77; RV32I-NEXT: sub a0, a0, a1 78; RV32I-NEXT: ret 79; 80; RV32ZBB-LABEL: select_abs8: 81; RV32ZBB: # %bb.0: 82; RV32ZBB-NEXT: sext.b a0, a0 83; RV32ZBB-NEXT: neg a1, a0 84; RV32ZBB-NEXT: max a0, a0, a1 85; RV32ZBB-NEXT: ret 86; 87; RV32ZBT-LABEL: select_abs8: 88; RV32ZBT: # %bb.0: 89; RV32ZBT-NEXT: slli a1, a0, 24 90; RV32ZBT-NEXT: srai a1, a1, 31 91; RV32ZBT-NEXT: xor a0, a0, a1 92; RV32ZBT-NEXT: sub a0, a0, a1 93; RV32ZBT-NEXT: ret 94; 95; RV64I-LABEL: select_abs8: 96; RV64I: # %bb.0: 97; RV64I-NEXT: slli a1, a0, 56 98; RV64I-NEXT: srai a1, a1, 63 99; RV64I-NEXT: xor a0, a0, a1 100; RV64I-NEXT: sub a0, a0, a1 101; RV64I-NEXT: ret 102; 103; RV64ZBB-LABEL: select_abs8: 104; RV64ZBB: # %bb.0: 105; RV64ZBB-NEXT: sext.b a0, a0 106; RV64ZBB-NEXT: neg a1, a0 107; RV64ZBB-NEXT: max a0, a0, a1 108; RV64ZBB-NEXT: ret 109; 110; RV64ZBT-LABEL: select_abs8: 111; RV64ZBT: # %bb.0: 112; RV64ZBT-NEXT: slli a1, a0, 56 113; RV64ZBT-NEXT: srai a1, a1, 63 114; RV64ZBT-NEXT: xor a0, a0, a1 115; RV64ZBT-NEXT: sub a0, a0, a1 116; RV64ZBT-NEXT: ret 117 %1 = icmp slt i8 %x, 0 118 %2 = sub nsw i8 0, %x 119 %3 = select i1 %1, i8 %2, i8 %x 120 ret i8 %3 121} 122 123define i16 @abs16(i16 %x) { 124; RV32I-LABEL: abs16: 125; RV32I: # %bb.0: 126; RV32I-NEXT: slli a1, a0, 16 127; RV32I-NEXT: srai a1, a1, 31 128; RV32I-NEXT: xor a0, a0, a1 129; RV32I-NEXT: sub a0, a0, a1 130; RV32I-NEXT: ret 131; 132; RV32ZBB-LABEL: abs16: 133; RV32ZBB: # %bb.0: 134; RV32ZBB-NEXT: sext.h a0, a0 135; RV32ZBB-NEXT: neg a1, a0 136; RV32ZBB-NEXT: max a0, a0, a1 137; RV32ZBB-NEXT: ret 138; 139; RV32ZBT-LABEL: abs16: 140; RV32ZBT: # %bb.0: 141; RV32ZBT-NEXT: slli a1, a0, 16 142; RV32ZBT-NEXT: srai a1, a1, 31 143; RV32ZBT-NEXT: xor a0, a0, a1 144; RV32ZBT-NEXT: sub a0, a0, a1 145; RV32ZBT-NEXT: ret 146; 147; RV64I-LABEL: abs16: 148; RV64I: # %bb.0: 149; RV64I-NEXT: slli a1, a0, 48 150; RV64I-NEXT: srai a1, a1, 63 151; RV64I-NEXT: xor a0, a0, a1 152; RV64I-NEXT: sub a0, a0, a1 153; RV64I-NEXT: ret 154; 155; RV64ZBB-LABEL: abs16: 156; RV64ZBB: # %bb.0: 157; RV64ZBB-NEXT: sext.h a0, a0 158; RV64ZBB-NEXT: neg a1, a0 159; RV64ZBB-NEXT: max a0, a0, a1 160; RV64ZBB-NEXT: ret 161; 162; RV64ZBT-LABEL: abs16: 163; RV64ZBT: # %bb.0: 164; RV64ZBT-NEXT: slli a1, a0, 48 165; RV64ZBT-NEXT: srai a1, a1, 63 166; RV64ZBT-NEXT: xor a0, a0, a1 167; RV64ZBT-NEXT: sub a0, a0, a1 168; RV64ZBT-NEXT: ret 169 %abs = tail call i16 @llvm.abs.i16(i16 %x, i1 true) 170 ret i16 %abs 171} 172 173define i16 @select_abs16(i16 %x) { 174; RV32I-LABEL: select_abs16: 175; RV32I: # %bb.0: 176; RV32I-NEXT: slli a1, a0, 16 177; RV32I-NEXT: srai a1, a1, 31 178; RV32I-NEXT: xor a0, a0, a1 179; RV32I-NEXT: sub a0, a0, a1 180; RV32I-NEXT: ret 181; 182; RV32ZBB-LABEL: select_abs16: 183; RV32ZBB: # %bb.0: 184; RV32ZBB-NEXT: sext.h a0, a0 185; RV32ZBB-NEXT: neg a1, a0 186; RV32ZBB-NEXT: max a0, a0, a1 187; RV32ZBB-NEXT: ret 188; 189; RV32ZBT-LABEL: select_abs16: 190; RV32ZBT: # %bb.0: 191; RV32ZBT-NEXT: slli a1, a0, 16 192; RV32ZBT-NEXT: srai a1, a1, 31 193; RV32ZBT-NEXT: xor a0, a0, a1 194; RV32ZBT-NEXT: sub a0, a0, a1 195; RV32ZBT-NEXT: ret 196; 197; RV64I-LABEL: select_abs16: 198; RV64I: # %bb.0: 199; RV64I-NEXT: slli a1, a0, 48 200; RV64I-NEXT: srai a1, a1, 63 201; RV64I-NEXT: xor a0, a0, a1 202; RV64I-NEXT: sub a0, a0, a1 203; RV64I-NEXT: ret 204; 205; RV64ZBB-LABEL: select_abs16: 206; RV64ZBB: # %bb.0: 207; RV64ZBB-NEXT: sext.h a0, a0 208; RV64ZBB-NEXT: neg a1, a0 209; RV64ZBB-NEXT: max a0, a0, a1 210; RV64ZBB-NEXT: ret 211; 212; RV64ZBT-LABEL: select_abs16: 213; RV64ZBT: # %bb.0: 214; RV64ZBT-NEXT: slli a1, a0, 48 215; RV64ZBT-NEXT: srai a1, a1, 63 216; RV64ZBT-NEXT: xor a0, a0, a1 217; RV64ZBT-NEXT: sub a0, a0, a1 218; RV64ZBT-NEXT: ret 219 %1 = icmp slt i16 %x, 0 220 %2 = sub nsw i16 0, %x 221 %3 = select i1 %1, i16 %2, i16 %x 222 ret i16 %3 223} 224 225define i32 @abs32(i32 %x) { 226; RV32I-LABEL: abs32: 227; RV32I: # %bb.0: 228; RV32I-NEXT: srai a1, a0, 31 229; RV32I-NEXT: xor a0, a0, a1 230; RV32I-NEXT: sub a0, a0, a1 231; RV32I-NEXT: ret 232; 233; RV32ZBB-LABEL: abs32: 234; RV32ZBB: # %bb.0: 235; RV32ZBB-NEXT: neg a1, a0 236; RV32ZBB-NEXT: max a0, a0, a1 237; RV32ZBB-NEXT: ret 238; 239; RV32ZBT-LABEL: abs32: 240; RV32ZBT: # %bb.0: 241; RV32ZBT-NEXT: srai a1, a0, 31 242; RV32ZBT-NEXT: xor a0, a0, a1 243; RV32ZBT-NEXT: sub a0, a0, a1 244; RV32ZBT-NEXT: ret 245; 246; RV64I-LABEL: abs32: 247; RV64I: # %bb.0: 248; RV64I-NEXT: sraiw a1, a0, 31 249; RV64I-NEXT: xor a0, a0, a1 250; RV64I-NEXT: subw a0, a0, a1 251; RV64I-NEXT: ret 252; 253; RV64ZBB-LABEL: abs32: 254; RV64ZBB: # %bb.0: 255; RV64ZBB-NEXT: sext.w a0, a0 256; RV64ZBB-NEXT: neg a1, a0 257; RV64ZBB-NEXT: max a0, a0, a1 258; RV64ZBB-NEXT: ret 259; 260; RV64ZBT-LABEL: abs32: 261; RV64ZBT: # %bb.0: 262; RV64ZBT-NEXT: sraiw a1, a0, 31 263; RV64ZBT-NEXT: xor a0, a0, a1 264; RV64ZBT-NEXT: subw a0, a0, a1 265; RV64ZBT-NEXT: ret 266 %abs = tail call i32 @llvm.abs.i32(i32 %x, i1 true) 267 ret i32 %abs 268} 269 270define i32 @select_abs32(i32 %x) { 271; RV32I-LABEL: select_abs32: 272; RV32I: # %bb.0: 273; RV32I-NEXT: srai a1, a0, 31 274; RV32I-NEXT: xor a0, a0, a1 275; RV32I-NEXT: sub a0, a0, a1 276; RV32I-NEXT: ret 277; 278; RV32ZBB-LABEL: select_abs32: 279; RV32ZBB: # %bb.0: 280; RV32ZBB-NEXT: neg a1, a0 281; RV32ZBB-NEXT: max a0, a0, a1 282; RV32ZBB-NEXT: ret 283; 284; RV32ZBT-LABEL: select_abs32: 285; RV32ZBT: # %bb.0: 286; RV32ZBT-NEXT: srai a1, a0, 31 287; RV32ZBT-NEXT: xor a0, a0, a1 288; RV32ZBT-NEXT: sub a0, a0, a1 289; RV32ZBT-NEXT: ret 290; 291; RV64I-LABEL: select_abs32: 292; RV64I: # %bb.0: 293; RV64I-NEXT: sraiw a1, a0, 31 294; RV64I-NEXT: xor a0, a0, a1 295; RV64I-NEXT: subw a0, a0, a1 296; RV64I-NEXT: ret 297; 298; RV64ZBB-LABEL: select_abs32: 299; RV64ZBB: # %bb.0: 300; RV64ZBB-NEXT: sext.w a0, a0 301; RV64ZBB-NEXT: neg a1, a0 302; RV64ZBB-NEXT: max a0, a0, a1 303; RV64ZBB-NEXT: ret 304; 305; RV64ZBT-LABEL: select_abs32: 306; RV64ZBT: # %bb.0: 307; RV64ZBT-NEXT: sraiw a1, a0, 31 308; RV64ZBT-NEXT: xor a0, a0, a1 309; RV64ZBT-NEXT: subw a0, a0, a1 310; RV64ZBT-NEXT: ret 311 %1 = icmp slt i32 %x, 0 312 %2 = sub nsw i32 0, %x 313 %3 = select i1 %1, i32 %2, i32 %x 314 ret i32 %3 315} 316 317define i64 @abs64(i64 %x) { 318; RV32I-LABEL: abs64: 319; RV32I: # %bb.0: 320; RV32I-NEXT: bgez a1, .LBB6_2 321; RV32I-NEXT: # %bb.1: 322; RV32I-NEXT: snez a2, a0 323; RV32I-NEXT: neg a0, a0 324; RV32I-NEXT: add a1, a1, a2 325; RV32I-NEXT: neg a1, a1 326; RV32I-NEXT: .LBB6_2: 327; RV32I-NEXT: ret 328; 329; RV32ZBB-LABEL: abs64: 330; RV32ZBB: # %bb.0: 331; RV32ZBB-NEXT: bgez a1, .LBB6_2 332; RV32ZBB-NEXT: # %bb.1: 333; RV32ZBB-NEXT: snez a2, a0 334; RV32ZBB-NEXT: neg a0, a0 335; RV32ZBB-NEXT: add a1, a1, a2 336; RV32ZBB-NEXT: neg a1, a1 337; RV32ZBB-NEXT: .LBB6_2: 338; RV32ZBB-NEXT: ret 339; 340; RV32ZBT-LABEL: abs64: 341; RV32ZBT: # %bb.0: 342; RV32ZBT-NEXT: neg a2, a0 343; RV32ZBT-NEXT: slti a3, a1, 0 344; RV32ZBT-NEXT: cmov a2, a3, a2, a0 345; RV32ZBT-NEXT: snez a0, a0 346; RV32ZBT-NEXT: add a0, a1, a0 347; RV32ZBT-NEXT: neg a0, a0 348; RV32ZBT-NEXT: cmov a1, a3, a0, a1 349; RV32ZBT-NEXT: mv a0, a2 350; RV32ZBT-NEXT: ret 351; 352; RV64I-LABEL: abs64: 353; RV64I: # %bb.0: 354; RV64I-NEXT: srai a1, a0, 63 355; RV64I-NEXT: xor a0, a0, a1 356; RV64I-NEXT: sub a0, a0, a1 357; RV64I-NEXT: ret 358; 359; RV64ZBB-LABEL: abs64: 360; RV64ZBB: # %bb.0: 361; RV64ZBB-NEXT: neg a1, a0 362; RV64ZBB-NEXT: max a0, a0, a1 363; RV64ZBB-NEXT: ret 364; 365; RV64ZBT-LABEL: abs64: 366; RV64ZBT: # %bb.0: 367; RV64ZBT-NEXT: srai a1, a0, 63 368; RV64ZBT-NEXT: xor a0, a0, a1 369; RV64ZBT-NEXT: sub a0, a0, a1 370; RV64ZBT-NEXT: ret 371 %abs = tail call i64 @llvm.abs.i64(i64 %x, i1 true) 372 ret i64 %abs 373} 374 375define i64 @select_abs64(i64 %x) { 376; RV32I-LABEL: select_abs64: 377; RV32I: # %bb.0: 378; RV32I-NEXT: bgez a1, .LBB7_2 379; RV32I-NEXT: # %bb.1: 380; RV32I-NEXT: snez a2, a0 381; RV32I-NEXT: neg a0, a0 382; RV32I-NEXT: add a1, a1, a2 383; RV32I-NEXT: neg a1, a1 384; RV32I-NEXT: .LBB7_2: 385; RV32I-NEXT: ret 386; 387; RV32ZBB-LABEL: select_abs64: 388; RV32ZBB: # %bb.0: 389; RV32ZBB-NEXT: bgez a1, .LBB7_2 390; RV32ZBB-NEXT: # %bb.1: 391; RV32ZBB-NEXT: snez a2, a0 392; RV32ZBB-NEXT: neg a0, a0 393; RV32ZBB-NEXT: add a1, a1, a2 394; RV32ZBB-NEXT: neg a1, a1 395; RV32ZBB-NEXT: .LBB7_2: 396; RV32ZBB-NEXT: ret 397; 398; RV32ZBT-LABEL: select_abs64: 399; RV32ZBT: # %bb.0: 400; RV32ZBT-NEXT: neg a2, a0 401; RV32ZBT-NEXT: slti a3, a1, 0 402; RV32ZBT-NEXT: cmov a2, a3, a2, a0 403; RV32ZBT-NEXT: snez a0, a0 404; RV32ZBT-NEXT: add a0, a1, a0 405; RV32ZBT-NEXT: neg a0, a0 406; RV32ZBT-NEXT: cmov a1, a3, a0, a1 407; RV32ZBT-NEXT: mv a0, a2 408; RV32ZBT-NEXT: ret 409; 410; RV64I-LABEL: select_abs64: 411; RV64I: # %bb.0: 412; RV64I-NEXT: srai a1, a0, 63 413; RV64I-NEXT: xor a0, a0, a1 414; RV64I-NEXT: sub a0, a0, a1 415; RV64I-NEXT: ret 416; 417; RV64ZBB-LABEL: select_abs64: 418; RV64ZBB: # %bb.0: 419; RV64ZBB-NEXT: neg a1, a0 420; RV64ZBB-NEXT: max a0, a0, a1 421; RV64ZBB-NEXT: ret 422; 423; RV64ZBT-LABEL: select_abs64: 424; RV64ZBT: # %bb.0: 425; RV64ZBT-NEXT: srai a1, a0, 63 426; RV64ZBT-NEXT: xor a0, a0, a1 427; RV64ZBT-NEXT: sub a0, a0, a1 428; RV64ZBT-NEXT: ret 429 %1 = icmp slt i64 %x, 0 430 %2 = sub nsw i64 0, %x 431 %3 = select i1 %1, i64 %2, i64 %x 432 ret i64 %3 433} 434 435define i128 @abs128(i128 %x) { 436; RV32I-LABEL: abs128: 437; RV32I: # %bb.0: 438; RV32I-NEXT: lw a3, 0(a1) 439; RV32I-NEXT: lw a2, 4(a1) 440; RV32I-NEXT: lw a4, 12(a1) 441; RV32I-NEXT: snez a5, a3 442; RV32I-NEXT: mv a6, a5 443; RV32I-NEXT: beqz a2, .LBB8_2 444; RV32I-NEXT: # %bb.1: 445; RV32I-NEXT: snez a6, a2 446; RV32I-NEXT: .LBB8_2: 447; RV32I-NEXT: lw a1, 8(a1) 448; RV32I-NEXT: bgez a4, .LBB8_4 449; RV32I-NEXT: # %bb.3: 450; RV32I-NEXT: neg a7, a1 451; RV32I-NEXT: sltu t0, a7, a6 452; RV32I-NEXT: snez a1, a1 453; RV32I-NEXT: add a1, a4, a1 454; RV32I-NEXT: add a1, a1, t0 455; RV32I-NEXT: neg a4, a1 456; RV32I-NEXT: sub a1, a7, a6 457; RV32I-NEXT: add a2, a2, a5 458; RV32I-NEXT: neg a2, a2 459; RV32I-NEXT: neg a3, a3 460; RV32I-NEXT: .LBB8_4: 461; RV32I-NEXT: sw a3, 0(a0) 462; RV32I-NEXT: sw a1, 8(a0) 463; RV32I-NEXT: sw a2, 4(a0) 464; RV32I-NEXT: sw a4, 12(a0) 465; RV32I-NEXT: ret 466; 467; RV32ZBB-LABEL: abs128: 468; RV32ZBB: # %bb.0: 469; RV32ZBB-NEXT: lw a3, 0(a1) 470; RV32ZBB-NEXT: lw a2, 4(a1) 471; RV32ZBB-NEXT: lw a4, 12(a1) 472; RV32ZBB-NEXT: snez a5, a3 473; RV32ZBB-NEXT: mv a6, a5 474; RV32ZBB-NEXT: beqz a2, .LBB8_2 475; RV32ZBB-NEXT: # %bb.1: 476; RV32ZBB-NEXT: snez a6, a2 477; RV32ZBB-NEXT: .LBB8_2: 478; RV32ZBB-NEXT: lw a1, 8(a1) 479; RV32ZBB-NEXT: bgez a4, .LBB8_4 480; RV32ZBB-NEXT: # %bb.3: 481; RV32ZBB-NEXT: neg a7, a1 482; RV32ZBB-NEXT: sltu t0, a7, a6 483; RV32ZBB-NEXT: snez a1, a1 484; RV32ZBB-NEXT: add a1, a4, a1 485; RV32ZBB-NEXT: add a1, a1, t0 486; RV32ZBB-NEXT: neg a4, a1 487; RV32ZBB-NEXT: sub a1, a7, a6 488; RV32ZBB-NEXT: add a2, a2, a5 489; RV32ZBB-NEXT: neg a2, a2 490; RV32ZBB-NEXT: neg a3, a3 491; RV32ZBB-NEXT: .LBB8_4: 492; RV32ZBB-NEXT: sw a3, 0(a0) 493; RV32ZBB-NEXT: sw a1, 8(a0) 494; RV32ZBB-NEXT: sw a2, 4(a0) 495; RV32ZBB-NEXT: sw a4, 12(a0) 496; RV32ZBB-NEXT: ret 497; 498; RV32ZBT-LABEL: abs128: 499; RV32ZBT: # %bb.0: 500; RV32ZBT-NEXT: lw a2, 0(a1) 501; RV32ZBT-NEXT: lw a3, 4(a1) 502; RV32ZBT-NEXT: lw a4, 12(a1) 503; RV32ZBT-NEXT: lw a1, 8(a1) 504; RV32ZBT-NEXT: snez a5, a2 505; RV32ZBT-NEXT: snez a6, a3 506; RV32ZBT-NEXT: cmov a6, a3, a6, a5 507; RV32ZBT-NEXT: neg a7, a1 508; RV32ZBT-NEXT: sltu t0, a7, a6 509; RV32ZBT-NEXT: snez t1, a1 510; RV32ZBT-NEXT: add t1, a4, t1 511; RV32ZBT-NEXT: add t0, t1, t0 512; RV32ZBT-NEXT: neg t0, t0 513; RV32ZBT-NEXT: slti t1, a4, 0 514; RV32ZBT-NEXT: cmov a4, t1, t0, a4 515; RV32ZBT-NEXT: sub a6, a7, a6 516; RV32ZBT-NEXT: cmov a1, t1, a6, a1 517; RV32ZBT-NEXT: add a5, a3, a5 518; RV32ZBT-NEXT: neg a5, a5 519; RV32ZBT-NEXT: cmov a3, t1, a5, a3 520; RV32ZBT-NEXT: neg a5, a2 521; RV32ZBT-NEXT: cmov a2, t1, a5, a2 522; RV32ZBT-NEXT: sw a2, 0(a0) 523; RV32ZBT-NEXT: sw a1, 8(a0) 524; RV32ZBT-NEXT: sw a3, 4(a0) 525; RV32ZBT-NEXT: sw a4, 12(a0) 526; RV32ZBT-NEXT: ret 527; 528; RV64I-LABEL: abs128: 529; RV64I: # %bb.0: 530; RV64I-NEXT: bgez a1, .LBB8_2 531; RV64I-NEXT: # %bb.1: 532; RV64I-NEXT: snez a2, a0 533; RV64I-NEXT: neg a0, a0 534; RV64I-NEXT: add a1, a1, a2 535; RV64I-NEXT: neg a1, a1 536; RV64I-NEXT: .LBB8_2: 537; RV64I-NEXT: ret 538; 539; RV64ZBB-LABEL: abs128: 540; RV64ZBB: # %bb.0: 541; RV64ZBB-NEXT: bgez a1, .LBB8_2 542; RV64ZBB-NEXT: # %bb.1: 543; RV64ZBB-NEXT: snez a2, a0 544; RV64ZBB-NEXT: neg a0, a0 545; RV64ZBB-NEXT: add a1, a1, a2 546; RV64ZBB-NEXT: neg a1, a1 547; RV64ZBB-NEXT: .LBB8_2: 548; RV64ZBB-NEXT: ret 549; 550; RV64ZBT-LABEL: abs128: 551; RV64ZBT: # %bb.0: 552; RV64ZBT-NEXT: neg a2, a0 553; RV64ZBT-NEXT: slti a3, a1, 0 554; RV64ZBT-NEXT: cmov a2, a3, a2, a0 555; RV64ZBT-NEXT: snez a0, a0 556; RV64ZBT-NEXT: add a0, a1, a0 557; RV64ZBT-NEXT: neg a0, a0 558; RV64ZBT-NEXT: cmov a1, a3, a0, a1 559; RV64ZBT-NEXT: mv a0, a2 560; RV64ZBT-NEXT: ret 561 %abs = tail call i128 @llvm.abs.i128(i128 %x, i1 true) 562 ret i128 %abs 563} 564 565define i128 @select_abs128(i128 %x) { 566; RV32I-LABEL: select_abs128: 567; RV32I: # %bb.0: 568; RV32I-NEXT: lw a3, 0(a1) 569; RV32I-NEXT: lw a2, 4(a1) 570; RV32I-NEXT: lw a4, 12(a1) 571; RV32I-NEXT: snez a5, a3 572; RV32I-NEXT: mv a6, a5 573; RV32I-NEXT: beqz a2, .LBB9_2 574; RV32I-NEXT: # %bb.1: 575; RV32I-NEXT: snez a6, a2 576; RV32I-NEXT: .LBB9_2: 577; RV32I-NEXT: lw a1, 8(a1) 578; RV32I-NEXT: bgez a4, .LBB9_4 579; RV32I-NEXT: # %bb.3: 580; RV32I-NEXT: neg a7, a1 581; RV32I-NEXT: sltu t0, a7, a6 582; RV32I-NEXT: snez a1, a1 583; RV32I-NEXT: add a1, a4, a1 584; RV32I-NEXT: add a1, a1, t0 585; RV32I-NEXT: neg a4, a1 586; RV32I-NEXT: sub a1, a7, a6 587; RV32I-NEXT: add a2, a2, a5 588; RV32I-NEXT: neg a2, a2 589; RV32I-NEXT: neg a3, a3 590; RV32I-NEXT: .LBB9_4: 591; RV32I-NEXT: sw a3, 0(a0) 592; RV32I-NEXT: sw a1, 8(a0) 593; RV32I-NEXT: sw a2, 4(a0) 594; RV32I-NEXT: sw a4, 12(a0) 595; RV32I-NEXT: ret 596; 597; RV32ZBB-LABEL: select_abs128: 598; RV32ZBB: # %bb.0: 599; RV32ZBB-NEXT: lw a3, 0(a1) 600; RV32ZBB-NEXT: lw a2, 4(a1) 601; RV32ZBB-NEXT: lw a4, 12(a1) 602; RV32ZBB-NEXT: snez a5, a3 603; RV32ZBB-NEXT: mv a6, a5 604; RV32ZBB-NEXT: beqz a2, .LBB9_2 605; RV32ZBB-NEXT: # %bb.1: 606; RV32ZBB-NEXT: snez a6, a2 607; RV32ZBB-NEXT: .LBB9_2: 608; RV32ZBB-NEXT: lw a1, 8(a1) 609; RV32ZBB-NEXT: bgez a4, .LBB9_4 610; RV32ZBB-NEXT: # %bb.3: 611; RV32ZBB-NEXT: neg a7, a1 612; RV32ZBB-NEXT: sltu t0, a7, a6 613; RV32ZBB-NEXT: snez a1, a1 614; RV32ZBB-NEXT: add a1, a4, a1 615; RV32ZBB-NEXT: add a1, a1, t0 616; RV32ZBB-NEXT: neg a4, a1 617; RV32ZBB-NEXT: sub a1, a7, a6 618; RV32ZBB-NEXT: add a2, a2, a5 619; RV32ZBB-NEXT: neg a2, a2 620; RV32ZBB-NEXT: neg a3, a3 621; RV32ZBB-NEXT: .LBB9_4: 622; RV32ZBB-NEXT: sw a3, 0(a0) 623; RV32ZBB-NEXT: sw a1, 8(a0) 624; RV32ZBB-NEXT: sw a2, 4(a0) 625; RV32ZBB-NEXT: sw a4, 12(a0) 626; RV32ZBB-NEXT: ret 627; 628; RV32ZBT-LABEL: select_abs128: 629; RV32ZBT: # %bb.0: 630; RV32ZBT-NEXT: lw a2, 0(a1) 631; RV32ZBT-NEXT: lw a3, 4(a1) 632; RV32ZBT-NEXT: lw a4, 12(a1) 633; RV32ZBT-NEXT: lw a1, 8(a1) 634; RV32ZBT-NEXT: snez a5, a2 635; RV32ZBT-NEXT: snez a6, a3 636; RV32ZBT-NEXT: cmov a6, a3, a6, a5 637; RV32ZBT-NEXT: neg a7, a1 638; RV32ZBT-NEXT: sltu t0, a7, a6 639; RV32ZBT-NEXT: snez t1, a1 640; RV32ZBT-NEXT: add t1, a4, t1 641; RV32ZBT-NEXT: add t0, t1, t0 642; RV32ZBT-NEXT: neg t0, t0 643; RV32ZBT-NEXT: slti t1, a4, 0 644; RV32ZBT-NEXT: cmov a4, t1, t0, a4 645; RV32ZBT-NEXT: sub a6, a7, a6 646; RV32ZBT-NEXT: cmov a1, t1, a6, a1 647; RV32ZBT-NEXT: add a5, a3, a5 648; RV32ZBT-NEXT: neg a5, a5 649; RV32ZBT-NEXT: cmov a3, t1, a5, a3 650; RV32ZBT-NEXT: neg a5, a2 651; RV32ZBT-NEXT: cmov a2, t1, a5, a2 652; RV32ZBT-NEXT: sw a2, 0(a0) 653; RV32ZBT-NEXT: sw a1, 8(a0) 654; RV32ZBT-NEXT: sw a3, 4(a0) 655; RV32ZBT-NEXT: sw a4, 12(a0) 656; RV32ZBT-NEXT: ret 657; 658; RV64I-LABEL: select_abs128: 659; RV64I: # %bb.0: 660; RV64I-NEXT: bgez a1, .LBB9_2 661; RV64I-NEXT: # %bb.1: 662; RV64I-NEXT: snez a2, a0 663; RV64I-NEXT: neg a0, a0 664; RV64I-NEXT: add a1, a1, a2 665; RV64I-NEXT: neg a1, a1 666; RV64I-NEXT: .LBB9_2: 667; RV64I-NEXT: ret 668; 669; RV64ZBB-LABEL: select_abs128: 670; RV64ZBB: # %bb.0: 671; RV64ZBB-NEXT: bgez a1, .LBB9_2 672; RV64ZBB-NEXT: # %bb.1: 673; RV64ZBB-NEXT: snez a2, a0 674; RV64ZBB-NEXT: neg a0, a0 675; RV64ZBB-NEXT: add a1, a1, a2 676; RV64ZBB-NEXT: neg a1, a1 677; RV64ZBB-NEXT: .LBB9_2: 678; RV64ZBB-NEXT: ret 679; 680; RV64ZBT-LABEL: select_abs128: 681; RV64ZBT: # %bb.0: 682; RV64ZBT-NEXT: neg a2, a0 683; RV64ZBT-NEXT: slti a3, a1, 0 684; RV64ZBT-NEXT: cmov a2, a3, a2, a0 685; RV64ZBT-NEXT: snez a0, a0 686; RV64ZBT-NEXT: add a0, a1, a0 687; RV64ZBT-NEXT: neg a0, a0 688; RV64ZBT-NEXT: cmov a1, a3, a0, a1 689; RV64ZBT-NEXT: mv a0, a2 690; RV64ZBT-NEXT: ret 691 %1 = icmp slt i128 %x, 0 692 %2 = sub nsw i128 0, %x 693 %3 = select i1 %1, i128 %2, i128 %x 694 ret i128 %3 695} 696 697define i64 @zext_abs32(i32 %x) { 698; RV32I-LABEL: zext_abs32: 699; RV32I: # %bb.0: 700; RV32I-NEXT: srai a1, a0, 31 701; RV32I-NEXT: xor a0, a0, a1 702; RV32I-NEXT: sub a0, a0, a1 703; RV32I-NEXT: li a1, 0 704; RV32I-NEXT: ret 705; 706; RV32ZBB-LABEL: zext_abs32: 707; RV32ZBB: # %bb.0: 708; RV32ZBB-NEXT: neg a1, a0 709; RV32ZBB-NEXT: max a0, a0, a1 710; RV32ZBB-NEXT: li a1, 0 711; RV32ZBB-NEXT: ret 712; 713; RV32ZBT-LABEL: zext_abs32: 714; RV32ZBT: # %bb.0: 715; RV32ZBT-NEXT: srai a1, a0, 31 716; RV32ZBT-NEXT: xor a0, a0, a1 717; RV32ZBT-NEXT: sub a0, a0, a1 718; RV32ZBT-NEXT: li a1, 0 719; RV32ZBT-NEXT: ret 720; 721; RV64I-LABEL: zext_abs32: 722; RV64I: # %bb.0: 723; RV64I-NEXT: sraiw a1, a0, 31 724; RV64I-NEXT: xor a0, a0, a1 725; RV64I-NEXT: subw a0, a0, a1 726; RV64I-NEXT: ret 727; 728; RV64ZBB-LABEL: zext_abs32: 729; RV64ZBB: # %bb.0: 730; RV64ZBB-NEXT: sext.w a0, a0 731; RV64ZBB-NEXT: negw a1, a0 732; RV64ZBB-NEXT: max a0, a0, a1 733; RV64ZBB-NEXT: ret 734; 735; RV64ZBT-LABEL: zext_abs32: 736; RV64ZBT: # %bb.0: 737; RV64ZBT-NEXT: sraiw a1, a0, 31 738; RV64ZBT-NEXT: xor a0, a0, a1 739; RV64ZBT-NEXT: subw a0, a0, a1 740; RV64ZBT-NEXT: ret 741 %abs = tail call i32 @llvm.abs.i32(i32 %x, i1 true) 742 %zext = zext i32 %abs to i64 743 ret i64 %zext 744} 745