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