1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 2; RUN: llc -mtriple=riscv32 -global-isel -verify-machineinstrs < %s \ 3; RUN: | FileCheck %s --check-prefixes=RV32I 4; RUN: llc -mtriple=riscv32 -global-isel -mattr=+zbb -verify-machineinstrs < %s \ 5; RUN: | FileCheck %s --check-prefixes=RV32ZBB 6; RUN: llc -mtriple=riscv64 -global-isel -verify-machineinstrs < %s \ 7; RUN: | FileCheck %s --check-prefixes=RV64I 8; RUN: llc -mtriple=riscv64 -global-isel -mattr=+zbb -verify-machineinstrs < %s \ 9; RUN: | FileCheck %s --check-prefixes=RV64ZBB 10 11define i32 @expanded_neg_abs32(i32 %x) { 12; RV32I-LABEL: expanded_neg_abs32: 13; RV32I: # %bb.0: 14; RV32I-NEXT: neg a1, a0 15; RV32I-NEXT: blt a0, a1, .LBB0_2 16; RV32I-NEXT: # %bb.1: 17; RV32I-NEXT: mv a1, a0 18; RV32I-NEXT: .LBB0_2: 19; RV32I-NEXT: neg a0, a1 20; RV32I-NEXT: ret 21; 22; RV32ZBB-LABEL: expanded_neg_abs32: 23; RV32ZBB: # %bb.0: 24; RV32ZBB-NEXT: neg a1, a0 25; RV32ZBB-NEXT: min a0, a0, a1 26; RV32ZBB-NEXT: ret 27; 28; RV64I-LABEL: expanded_neg_abs32: 29; RV64I: # %bb.0: 30; RV64I-NEXT: negw a1, a0 31; RV64I-NEXT: sext.w a2, a0 32; RV64I-NEXT: blt a2, a1, .LBB0_2 33; RV64I-NEXT: # %bb.1: 34; RV64I-NEXT: mv a1, a0 35; RV64I-NEXT: .LBB0_2: 36; RV64I-NEXT: negw a0, a1 37; RV64I-NEXT: ret 38; 39; RV64ZBB-LABEL: expanded_neg_abs32: 40; RV64ZBB: # %bb.0: 41; RV64ZBB-NEXT: negw a1, a0 42; RV64ZBB-NEXT: sext.w a0, a0 43; RV64ZBB-NEXT: max a0, a1, a0 44; RV64ZBB-NEXT: negw a0, a0 45; RV64ZBB-NEXT: ret 46 %n = sub i32 0, %x 47 %t = call i32 @llvm.smax.i32(i32 %n, i32 %x) 48 %r = sub i32 0, %t 49 ret i32 %r 50} 51 52define i32 @expanded_neg_abs32_unsigned(i32 %x) { 53; RV32I-LABEL: expanded_neg_abs32_unsigned: 54; RV32I: # %bb.0: 55; RV32I-NEXT: neg a1, a0 56; RV32I-NEXT: bltu a0, a1, .LBB1_2 57; RV32I-NEXT: # %bb.1: 58; RV32I-NEXT: mv a1, a0 59; RV32I-NEXT: .LBB1_2: 60; RV32I-NEXT: neg a0, a1 61; RV32I-NEXT: ret 62; 63; RV32ZBB-LABEL: expanded_neg_abs32_unsigned: 64; RV32ZBB: # %bb.0: 65; RV32ZBB-NEXT: neg a1, a0 66; RV32ZBB-NEXT: minu a0, a0, a1 67; RV32ZBB-NEXT: ret 68; 69; RV64I-LABEL: expanded_neg_abs32_unsigned: 70; RV64I: # %bb.0: 71; RV64I-NEXT: negw a1, a0 72; RV64I-NEXT: sext.w a2, a0 73; RV64I-NEXT: bltu a2, a1, .LBB1_2 74; RV64I-NEXT: # %bb.1: 75; RV64I-NEXT: mv a1, a0 76; RV64I-NEXT: .LBB1_2: 77; RV64I-NEXT: negw a0, a1 78; RV64I-NEXT: ret 79; 80; RV64ZBB-LABEL: expanded_neg_abs32_unsigned: 81; RV64ZBB: # %bb.0: 82; RV64ZBB-NEXT: negw a1, a0 83; RV64ZBB-NEXT: sext.w a0, a0 84; RV64ZBB-NEXT: maxu a0, a1, a0 85; RV64ZBB-NEXT: negw a0, a0 86; RV64ZBB-NEXT: ret 87 %n = sub i32 0, %x 88 %t = call i32 @llvm.umax.i32(i32 %n, i32 %x) 89 %r = sub i32 0, %t 90 ret i32 %r 91} 92 93define i64 @expanded_neg_abs64(i64 %x) { 94; RV32I-LABEL: expanded_neg_abs64: 95; RV32I: # %bb.0: 96; RV32I-NEXT: snez a2, a0 97; RV32I-NEXT: neg a3, a1 98; RV32I-NEXT: sub a2, a3, a2 99; RV32I-NEXT: neg a3, a0 100; RV32I-NEXT: beq a2, a1, .LBB2_2 101; RV32I-NEXT: # %bb.1: 102; RV32I-NEXT: slt a4, a1, a2 103; RV32I-NEXT: beqz a4, .LBB2_3 104; RV32I-NEXT: j .LBB2_4 105; RV32I-NEXT: .LBB2_2: 106; RV32I-NEXT: sltu a4, a0, a3 107; RV32I-NEXT: bnez a4, .LBB2_4 108; RV32I-NEXT: .LBB2_3: 109; RV32I-NEXT: mv a3, a0 110; RV32I-NEXT: mv a2, a1 111; RV32I-NEXT: .LBB2_4: 112; RV32I-NEXT: neg a0, a3 113; RV32I-NEXT: snez a1, a3 114; RV32I-NEXT: neg a2, a2 115; RV32I-NEXT: sub a1, a2, a1 116; RV32I-NEXT: ret 117; 118; RV32ZBB-LABEL: expanded_neg_abs64: 119; RV32ZBB: # %bb.0: 120; RV32ZBB-NEXT: snez a2, a0 121; RV32ZBB-NEXT: neg a3, a1 122; RV32ZBB-NEXT: sub a2, a3, a2 123; RV32ZBB-NEXT: neg a3, a0 124; RV32ZBB-NEXT: beq a2, a1, .LBB2_2 125; RV32ZBB-NEXT: # %bb.1: 126; RV32ZBB-NEXT: slt a4, a1, a2 127; RV32ZBB-NEXT: beqz a4, .LBB2_3 128; RV32ZBB-NEXT: j .LBB2_4 129; RV32ZBB-NEXT: .LBB2_2: 130; RV32ZBB-NEXT: sltu a4, a0, a3 131; RV32ZBB-NEXT: bnez a4, .LBB2_4 132; RV32ZBB-NEXT: .LBB2_3: 133; RV32ZBB-NEXT: mv a3, a0 134; RV32ZBB-NEXT: mv a2, a1 135; RV32ZBB-NEXT: .LBB2_4: 136; RV32ZBB-NEXT: neg a0, a3 137; RV32ZBB-NEXT: snez a1, a3 138; RV32ZBB-NEXT: neg a2, a2 139; RV32ZBB-NEXT: sub a1, a2, a1 140; RV32ZBB-NEXT: ret 141; 142; RV64I-LABEL: expanded_neg_abs64: 143; RV64I: # %bb.0: 144; RV64I-NEXT: neg a1, a0 145; RV64I-NEXT: blt a0, a1, .LBB2_2 146; RV64I-NEXT: # %bb.1: 147; RV64I-NEXT: mv a1, a0 148; RV64I-NEXT: .LBB2_2: 149; RV64I-NEXT: neg a0, a1 150; RV64I-NEXT: ret 151; 152; RV64ZBB-LABEL: expanded_neg_abs64: 153; RV64ZBB: # %bb.0: 154; RV64ZBB-NEXT: neg a1, a0 155; RV64ZBB-NEXT: min a0, a0, a1 156; RV64ZBB-NEXT: ret 157 %n = sub i64 0, %x 158 %t = call i64 @llvm.smax.i64(i64 %n, i64 %x) 159 %r = sub i64 0, %t 160 ret i64 %r 161} 162 163define i64 @expanded_neg_abs64_unsigned(i64 %x) { 164; RV32I-LABEL: expanded_neg_abs64_unsigned: 165; RV32I: # %bb.0: 166; RV32I-NEXT: snez a2, a0 167; RV32I-NEXT: neg a3, a1 168; RV32I-NEXT: sub a2, a3, a2 169; RV32I-NEXT: neg a3, a0 170; RV32I-NEXT: beq a2, a1, .LBB3_2 171; RV32I-NEXT: # %bb.1: 172; RV32I-NEXT: sltu a4, a1, a2 173; RV32I-NEXT: beqz a4, .LBB3_3 174; RV32I-NEXT: j .LBB3_4 175; RV32I-NEXT: .LBB3_2: 176; RV32I-NEXT: sltu a4, a0, a3 177; RV32I-NEXT: bnez a4, .LBB3_4 178; RV32I-NEXT: .LBB3_3: 179; RV32I-NEXT: mv a3, a0 180; RV32I-NEXT: mv a2, a1 181; RV32I-NEXT: .LBB3_4: 182; RV32I-NEXT: neg a0, a3 183; RV32I-NEXT: snez a1, a3 184; RV32I-NEXT: neg a2, a2 185; RV32I-NEXT: sub a1, a2, a1 186; RV32I-NEXT: ret 187; 188; RV32ZBB-LABEL: expanded_neg_abs64_unsigned: 189; RV32ZBB: # %bb.0: 190; RV32ZBB-NEXT: snez a2, a0 191; RV32ZBB-NEXT: neg a3, a1 192; RV32ZBB-NEXT: sub a2, a3, a2 193; RV32ZBB-NEXT: neg a3, a0 194; RV32ZBB-NEXT: beq a2, a1, .LBB3_2 195; RV32ZBB-NEXT: # %bb.1: 196; RV32ZBB-NEXT: sltu a4, a1, a2 197; RV32ZBB-NEXT: beqz a4, .LBB3_3 198; RV32ZBB-NEXT: j .LBB3_4 199; RV32ZBB-NEXT: .LBB3_2: 200; RV32ZBB-NEXT: sltu a4, a0, a3 201; RV32ZBB-NEXT: bnez a4, .LBB3_4 202; RV32ZBB-NEXT: .LBB3_3: 203; RV32ZBB-NEXT: mv a3, a0 204; RV32ZBB-NEXT: mv a2, a1 205; RV32ZBB-NEXT: .LBB3_4: 206; RV32ZBB-NEXT: neg a0, a3 207; RV32ZBB-NEXT: snez a1, a3 208; RV32ZBB-NEXT: neg a2, a2 209; RV32ZBB-NEXT: sub a1, a2, a1 210; RV32ZBB-NEXT: ret 211; 212; RV64I-LABEL: expanded_neg_abs64_unsigned: 213; RV64I: # %bb.0: 214; RV64I-NEXT: neg a1, a0 215; RV64I-NEXT: bltu a0, a1, .LBB3_2 216; RV64I-NEXT: # %bb.1: 217; RV64I-NEXT: mv a1, a0 218; RV64I-NEXT: .LBB3_2: 219; RV64I-NEXT: neg a0, a1 220; RV64I-NEXT: ret 221; 222; RV64ZBB-LABEL: expanded_neg_abs64_unsigned: 223; RV64ZBB: # %bb.0: 224; RV64ZBB-NEXT: neg a1, a0 225; RV64ZBB-NEXT: minu a0, a0, a1 226; RV64ZBB-NEXT: ret 227 %n = sub i64 0, %x 228 %t = call i64 @llvm.umax.i64(i64 %n, i64 %x) 229 %r = sub i64 0, %t 230 ret i64 %r 231} 232 233define i32 @expanded_neg_inv_abs32(i32 %x) { 234; RV32I-LABEL: expanded_neg_inv_abs32: 235; RV32I: # %bb.0: 236; RV32I-NEXT: neg a1, a0 237; RV32I-NEXT: blt a1, a0, .LBB4_2 238; RV32I-NEXT: # %bb.1: 239; RV32I-NEXT: mv a1, a0 240; RV32I-NEXT: .LBB4_2: 241; RV32I-NEXT: neg a0, a1 242; RV32I-NEXT: ret 243; 244; RV32ZBB-LABEL: expanded_neg_inv_abs32: 245; RV32ZBB: # %bb.0: 246; RV32ZBB-NEXT: neg a1, a0 247; RV32ZBB-NEXT: max a0, a0, a1 248; RV32ZBB-NEXT: ret 249; 250; RV64I-LABEL: expanded_neg_inv_abs32: 251; RV64I: # %bb.0: 252; RV64I-NEXT: negw a1, a0 253; RV64I-NEXT: sext.w a2, a0 254; RV64I-NEXT: blt a1, a2, .LBB4_2 255; RV64I-NEXT: # %bb.1: 256; RV64I-NEXT: mv a1, a0 257; RV64I-NEXT: .LBB4_2: 258; RV64I-NEXT: negw a0, a1 259; RV64I-NEXT: ret 260; 261; RV64ZBB-LABEL: expanded_neg_inv_abs32: 262; RV64ZBB: # %bb.0: 263; RV64ZBB-NEXT: negw a1, a0 264; RV64ZBB-NEXT: sext.w a0, a0 265; RV64ZBB-NEXT: min a0, a1, a0 266; RV64ZBB-NEXT: negw a0, a0 267; RV64ZBB-NEXT: ret 268 %n = sub i32 0, %x 269 %t = call i32 @llvm.smin.i32(i32 %n, i32 %x) 270 %r = sub i32 0, %t 271 ret i32 %r 272} 273 274define i32 @expanded_neg_inv_abs32_unsigned(i32 %x) { 275; RV32I-LABEL: expanded_neg_inv_abs32_unsigned: 276; RV32I: # %bb.0: 277; RV32I-NEXT: neg a1, a0 278; RV32I-NEXT: bltu a1, a0, .LBB5_2 279; RV32I-NEXT: # %bb.1: 280; RV32I-NEXT: mv a1, a0 281; RV32I-NEXT: .LBB5_2: 282; RV32I-NEXT: neg a0, a1 283; RV32I-NEXT: ret 284; 285; RV32ZBB-LABEL: expanded_neg_inv_abs32_unsigned: 286; RV32ZBB: # %bb.0: 287; RV32ZBB-NEXT: neg a1, a0 288; RV32ZBB-NEXT: maxu a0, a0, a1 289; RV32ZBB-NEXT: ret 290; 291; RV64I-LABEL: expanded_neg_inv_abs32_unsigned: 292; RV64I: # %bb.0: 293; RV64I-NEXT: negw a1, a0 294; RV64I-NEXT: sext.w a2, a0 295; RV64I-NEXT: bltu a1, a2, .LBB5_2 296; RV64I-NEXT: # %bb.1: 297; RV64I-NEXT: mv a1, a0 298; RV64I-NEXT: .LBB5_2: 299; RV64I-NEXT: negw a0, a1 300; RV64I-NEXT: ret 301; 302; RV64ZBB-LABEL: expanded_neg_inv_abs32_unsigned: 303; RV64ZBB: # %bb.0: 304; RV64ZBB-NEXT: negw a1, a0 305; RV64ZBB-NEXT: sext.w a0, a0 306; RV64ZBB-NEXT: minu a0, a1, a0 307; RV64ZBB-NEXT: negw a0, a0 308; RV64ZBB-NEXT: ret 309 %n = sub i32 0, %x 310 %t = call i32 @llvm.umin.i32(i32 %n, i32 %x) 311 %r = sub i32 0, %t 312 ret i32 %r 313} 314 315define i64 @expanded_neg_inv_abs64(i64 %x) { 316; RV32I-LABEL: expanded_neg_inv_abs64: 317; RV32I: # %bb.0: 318; RV32I-NEXT: snez a2, a0 319; RV32I-NEXT: neg a3, a1 320; RV32I-NEXT: sub a2, a3, a2 321; RV32I-NEXT: neg a3, a0 322; RV32I-NEXT: beq a2, a1, .LBB6_2 323; RV32I-NEXT: # %bb.1: 324; RV32I-NEXT: slt a4, a2, a1 325; RV32I-NEXT: beqz a4, .LBB6_3 326; RV32I-NEXT: j .LBB6_4 327; RV32I-NEXT: .LBB6_2: 328; RV32I-NEXT: sltu a4, a3, a0 329; RV32I-NEXT: bnez a4, .LBB6_4 330; RV32I-NEXT: .LBB6_3: 331; RV32I-NEXT: mv a3, a0 332; RV32I-NEXT: mv a2, a1 333; RV32I-NEXT: .LBB6_4: 334; RV32I-NEXT: neg a0, a3 335; RV32I-NEXT: snez a1, a3 336; RV32I-NEXT: neg a2, a2 337; RV32I-NEXT: sub a1, a2, a1 338; RV32I-NEXT: ret 339; 340; RV32ZBB-LABEL: expanded_neg_inv_abs64: 341; RV32ZBB: # %bb.0: 342; RV32ZBB-NEXT: snez a2, a0 343; RV32ZBB-NEXT: neg a3, a1 344; RV32ZBB-NEXT: sub a2, a3, a2 345; RV32ZBB-NEXT: neg a3, a0 346; RV32ZBB-NEXT: beq a2, a1, .LBB6_2 347; RV32ZBB-NEXT: # %bb.1: 348; RV32ZBB-NEXT: slt a4, a2, a1 349; RV32ZBB-NEXT: beqz a4, .LBB6_3 350; RV32ZBB-NEXT: j .LBB6_4 351; RV32ZBB-NEXT: .LBB6_2: 352; RV32ZBB-NEXT: sltu a4, a3, a0 353; RV32ZBB-NEXT: bnez a4, .LBB6_4 354; RV32ZBB-NEXT: .LBB6_3: 355; RV32ZBB-NEXT: mv a3, a0 356; RV32ZBB-NEXT: mv a2, a1 357; RV32ZBB-NEXT: .LBB6_4: 358; RV32ZBB-NEXT: neg a0, a3 359; RV32ZBB-NEXT: snez a1, a3 360; RV32ZBB-NEXT: neg a2, a2 361; RV32ZBB-NEXT: sub a1, a2, a1 362; RV32ZBB-NEXT: ret 363; 364; RV64I-LABEL: expanded_neg_inv_abs64: 365; RV64I: # %bb.0: 366; RV64I-NEXT: neg a1, a0 367; RV64I-NEXT: blt a1, a0, .LBB6_2 368; RV64I-NEXT: # %bb.1: 369; RV64I-NEXT: mv a1, a0 370; RV64I-NEXT: .LBB6_2: 371; RV64I-NEXT: neg a0, a1 372; RV64I-NEXT: ret 373; 374; RV64ZBB-LABEL: expanded_neg_inv_abs64: 375; RV64ZBB: # %bb.0: 376; RV64ZBB-NEXT: neg a1, a0 377; RV64ZBB-NEXT: max a0, a0, a1 378; RV64ZBB-NEXT: ret 379 %n = sub i64 0, %x 380 %t = call i64 @llvm.smin.i64(i64 %n, i64 %x) 381 %r = sub i64 0, %t 382 ret i64 %r 383} 384 385define i64 @expanded_neg_inv_abs64_unsigned(i64 %x) { 386; RV32I-LABEL: expanded_neg_inv_abs64_unsigned: 387; RV32I: # %bb.0: 388; RV32I-NEXT: snez a2, a0 389; RV32I-NEXT: neg a3, a1 390; RV32I-NEXT: sub a2, a3, a2 391; RV32I-NEXT: neg a3, a0 392; RV32I-NEXT: beq a2, a1, .LBB7_2 393; RV32I-NEXT: # %bb.1: 394; RV32I-NEXT: sltu a4, a2, a1 395; RV32I-NEXT: beqz a4, .LBB7_3 396; RV32I-NEXT: j .LBB7_4 397; RV32I-NEXT: .LBB7_2: 398; RV32I-NEXT: sltu a4, a3, a0 399; RV32I-NEXT: bnez a4, .LBB7_4 400; RV32I-NEXT: .LBB7_3: 401; RV32I-NEXT: mv a3, a0 402; RV32I-NEXT: mv a2, a1 403; RV32I-NEXT: .LBB7_4: 404; RV32I-NEXT: neg a0, a3 405; RV32I-NEXT: snez a1, a3 406; RV32I-NEXT: neg a2, a2 407; RV32I-NEXT: sub a1, a2, a1 408; RV32I-NEXT: ret 409; 410; RV32ZBB-LABEL: expanded_neg_inv_abs64_unsigned: 411; RV32ZBB: # %bb.0: 412; RV32ZBB-NEXT: snez a2, a0 413; RV32ZBB-NEXT: neg a3, a1 414; RV32ZBB-NEXT: sub a2, a3, a2 415; RV32ZBB-NEXT: neg a3, a0 416; RV32ZBB-NEXT: beq a2, a1, .LBB7_2 417; RV32ZBB-NEXT: # %bb.1: 418; RV32ZBB-NEXT: sltu a4, a2, a1 419; RV32ZBB-NEXT: beqz a4, .LBB7_3 420; RV32ZBB-NEXT: j .LBB7_4 421; RV32ZBB-NEXT: .LBB7_2: 422; RV32ZBB-NEXT: sltu a4, a3, a0 423; RV32ZBB-NEXT: bnez a4, .LBB7_4 424; RV32ZBB-NEXT: .LBB7_3: 425; RV32ZBB-NEXT: mv a3, a0 426; RV32ZBB-NEXT: mv a2, a1 427; RV32ZBB-NEXT: .LBB7_4: 428; RV32ZBB-NEXT: neg a0, a3 429; RV32ZBB-NEXT: snez a1, a3 430; RV32ZBB-NEXT: neg a2, a2 431; RV32ZBB-NEXT: sub a1, a2, a1 432; RV32ZBB-NEXT: ret 433; 434; RV64I-LABEL: expanded_neg_inv_abs64_unsigned: 435; RV64I: # %bb.0: 436; RV64I-NEXT: neg a1, a0 437; RV64I-NEXT: bltu a1, a0, .LBB7_2 438; RV64I-NEXT: # %bb.1: 439; RV64I-NEXT: mv a1, a0 440; RV64I-NEXT: .LBB7_2: 441; RV64I-NEXT: neg a0, a1 442; RV64I-NEXT: ret 443; 444; RV64ZBB-LABEL: expanded_neg_inv_abs64_unsigned: 445; RV64ZBB: # %bb.0: 446; RV64ZBB-NEXT: neg a1, a0 447; RV64ZBB-NEXT: maxu a0, a0, a1 448; RV64ZBB-NEXT: ret 449 %n = sub i64 0, %x 450 %t = call i64 @llvm.umin.i64(i64 %n, i64 %x) 451 %r = sub i64 0, %t 452 ret i64 %r 453} 454