1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=riscv32 -mattr=+m -verify-machineinstrs | FileCheck %s --check-prefix=RV32 3; RUN: llc < %s -mtriple=riscv64 -mattr=+m -verify-machineinstrs | FileCheck %s --check-prefix=RV64 4; RUN: llc < %s -mtriple=riscv32 -mattr=+m,+zba -verify-machineinstrs | FileCheck %s --check-prefix=RV32ZBA 5; RUN: llc < %s -mtriple=riscv64 -mattr=+m,+zba -verify-machineinstrs | FileCheck %s --check-prefix=RV64ZBA 6; RUN: llc < %s -mtriple=riscv32 -mattr=+m,+zicond -verify-machineinstrs | FileCheck %s --check-prefix=RV32ZICOND 7; RUN: llc < %s -mtriple=riscv64 -mattr=+m,+zicond -verify-machineinstrs | FileCheck %s --check-prefix=RV64ZICOND 8 9; 10; Get the actual value of the overflow bit. 11; 12define zeroext i1 @saddo1.i32(i32 signext %v1, i32 signext %v2, ptr %res) { 13; RV32-LABEL: saddo1.i32: 14; RV32: # %bb.0: # %entry 15; RV32-NEXT: add a3, a0, a1 16; RV32-NEXT: slt a0, a3, a0 17; RV32-NEXT: slti a1, a1, 0 18; RV32-NEXT: xor a0, a1, a0 19; RV32-NEXT: sw a3, 0(a2) 20; RV32-NEXT: ret 21; 22; RV64-LABEL: saddo1.i32: 23; RV64: # %bb.0: # %entry 24; RV64-NEXT: add a3, a0, a1 25; RV64-NEXT: addw a0, a0, a1 26; RV64-NEXT: xor a0, a0, a3 27; RV64-NEXT: snez a0, a0 28; RV64-NEXT: sw a3, 0(a2) 29; RV64-NEXT: ret 30; 31; RV32ZBA-LABEL: saddo1.i32: 32; RV32ZBA: # %bb.0: # %entry 33; RV32ZBA-NEXT: add a3, a0, a1 34; RV32ZBA-NEXT: slt a0, a3, a0 35; RV32ZBA-NEXT: slti a1, a1, 0 36; RV32ZBA-NEXT: xor a0, a1, a0 37; RV32ZBA-NEXT: sw a3, 0(a2) 38; RV32ZBA-NEXT: ret 39; 40; RV64ZBA-LABEL: saddo1.i32: 41; RV64ZBA: # %bb.0: # %entry 42; RV64ZBA-NEXT: add a3, a0, a1 43; RV64ZBA-NEXT: addw a0, a0, a1 44; RV64ZBA-NEXT: xor a0, a0, a3 45; RV64ZBA-NEXT: snez a0, a0 46; RV64ZBA-NEXT: sw a3, 0(a2) 47; RV64ZBA-NEXT: ret 48; 49; RV32ZICOND-LABEL: saddo1.i32: 50; RV32ZICOND: # %bb.0: # %entry 51; RV32ZICOND-NEXT: add a3, a0, a1 52; RV32ZICOND-NEXT: slt a0, a3, a0 53; RV32ZICOND-NEXT: slti a1, a1, 0 54; RV32ZICOND-NEXT: xor a0, a1, a0 55; RV32ZICOND-NEXT: sw a3, 0(a2) 56; RV32ZICOND-NEXT: ret 57; 58; RV64ZICOND-LABEL: saddo1.i32: 59; RV64ZICOND: # %bb.0: # %entry 60; RV64ZICOND-NEXT: add a3, a0, a1 61; RV64ZICOND-NEXT: addw a0, a0, a1 62; RV64ZICOND-NEXT: xor a0, a0, a3 63; RV64ZICOND-NEXT: snez a0, a0 64; RV64ZICOND-NEXT: sw a3, 0(a2) 65; RV64ZICOND-NEXT: ret 66entry: 67 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2) 68 %val = extractvalue {i32, i1} %t, 0 69 %obit = extractvalue {i32, i1} %t, 1 70 store i32 %val, ptr %res 71 ret i1 %obit 72} 73 74; Test the immediate version. 75define zeroext i1 @saddo2.i32(i32 signext %v1, ptr %res) { 76; RV32-LABEL: saddo2.i32: 77; RV32: # %bb.0: # %entry 78; RV32-NEXT: addi a2, a0, 4 79; RV32-NEXT: slt a0, a2, a0 80; RV32-NEXT: sw a2, 0(a1) 81; RV32-NEXT: ret 82; 83; RV64-LABEL: saddo2.i32: 84; RV64: # %bb.0: # %entry 85; RV64-NEXT: addiw a2, a0, 4 86; RV64-NEXT: slt a0, a2, a0 87; RV64-NEXT: sw a2, 0(a1) 88; RV64-NEXT: ret 89; 90; RV32ZBA-LABEL: saddo2.i32: 91; RV32ZBA: # %bb.0: # %entry 92; RV32ZBA-NEXT: addi a2, a0, 4 93; RV32ZBA-NEXT: slt a0, a2, a0 94; RV32ZBA-NEXT: sw a2, 0(a1) 95; RV32ZBA-NEXT: ret 96; 97; RV64ZBA-LABEL: saddo2.i32: 98; RV64ZBA: # %bb.0: # %entry 99; RV64ZBA-NEXT: addiw a2, a0, 4 100; RV64ZBA-NEXT: slt a0, a2, a0 101; RV64ZBA-NEXT: sw a2, 0(a1) 102; RV64ZBA-NEXT: ret 103; 104; RV32ZICOND-LABEL: saddo2.i32: 105; RV32ZICOND: # %bb.0: # %entry 106; RV32ZICOND-NEXT: addi a2, a0, 4 107; RV32ZICOND-NEXT: slt a0, a2, a0 108; RV32ZICOND-NEXT: sw a2, 0(a1) 109; RV32ZICOND-NEXT: ret 110; 111; RV64ZICOND-LABEL: saddo2.i32: 112; RV64ZICOND: # %bb.0: # %entry 113; RV64ZICOND-NEXT: addiw a2, a0, 4 114; RV64ZICOND-NEXT: slt a0, a2, a0 115; RV64ZICOND-NEXT: sw a2, 0(a1) 116; RV64ZICOND-NEXT: ret 117entry: 118 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 4) 119 %val = extractvalue {i32, i1} %t, 0 120 %obit = extractvalue {i32, i1} %t, 1 121 store i32 %val, ptr %res 122 ret i1 %obit 123} 124 125; Test negative immediates. 126define zeroext i1 @saddo3.i32(i32 signext %v1, ptr %res) { 127; RV32-LABEL: saddo3.i32: 128; RV32: # %bb.0: # %entry 129; RV32-NEXT: addi a2, a0, -4 130; RV32-NEXT: slt a0, a2, a0 131; RV32-NEXT: xori a0, a0, 1 132; RV32-NEXT: sw a2, 0(a1) 133; RV32-NEXT: ret 134; 135; RV64-LABEL: saddo3.i32: 136; RV64: # %bb.0: # %entry 137; RV64-NEXT: addiw a2, a0, -4 138; RV64-NEXT: slt a0, a2, a0 139; RV64-NEXT: xori a0, a0, 1 140; RV64-NEXT: sw a2, 0(a1) 141; RV64-NEXT: ret 142; 143; RV32ZBA-LABEL: saddo3.i32: 144; RV32ZBA: # %bb.0: # %entry 145; RV32ZBA-NEXT: addi a2, a0, -4 146; RV32ZBA-NEXT: slt a0, a2, a0 147; RV32ZBA-NEXT: xori a0, a0, 1 148; RV32ZBA-NEXT: sw a2, 0(a1) 149; RV32ZBA-NEXT: ret 150; 151; RV64ZBA-LABEL: saddo3.i32: 152; RV64ZBA: # %bb.0: # %entry 153; RV64ZBA-NEXT: addiw a2, a0, -4 154; RV64ZBA-NEXT: slt a0, a2, a0 155; RV64ZBA-NEXT: xori a0, a0, 1 156; RV64ZBA-NEXT: sw a2, 0(a1) 157; RV64ZBA-NEXT: ret 158; 159; RV32ZICOND-LABEL: saddo3.i32: 160; RV32ZICOND: # %bb.0: # %entry 161; RV32ZICOND-NEXT: addi a2, a0, -4 162; RV32ZICOND-NEXT: slt a0, a2, a0 163; RV32ZICOND-NEXT: xori a0, a0, 1 164; RV32ZICOND-NEXT: sw a2, 0(a1) 165; RV32ZICOND-NEXT: ret 166; 167; RV64ZICOND-LABEL: saddo3.i32: 168; RV64ZICOND: # %bb.0: # %entry 169; RV64ZICOND-NEXT: addiw a2, a0, -4 170; RV64ZICOND-NEXT: slt a0, a2, a0 171; RV64ZICOND-NEXT: xori a0, a0, 1 172; RV64ZICOND-NEXT: sw a2, 0(a1) 173; RV64ZICOND-NEXT: ret 174entry: 175 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 -4) 176 %val = extractvalue {i32, i1} %t, 0 177 %obit = extractvalue {i32, i1} %t, 1 178 store i32 %val, ptr %res 179 ret i1 %obit 180} 181 182; Test immediates that are too large to be encoded. 183define zeroext i1 @saddo4.i32(i32 signext %v1, ptr %res) { 184; RV32-LABEL: saddo4.i32: 185; RV32: # %bb.0: # %entry 186; RV32-NEXT: lui a2, 4096 187; RV32-NEXT: addi a2, a2, -1 188; RV32-NEXT: add a2, a0, a2 189; RV32-NEXT: slt a0, a2, a0 190; RV32-NEXT: sw a2, 0(a1) 191; RV32-NEXT: ret 192; 193; RV64-LABEL: saddo4.i32: 194; RV64: # %bb.0: # %entry 195; RV64-NEXT: lui a2, 4096 196; RV64-NEXT: addi a2, a2, -1 197; RV64-NEXT: addw a2, a0, a2 198; RV64-NEXT: slt a0, a2, a0 199; RV64-NEXT: sw a2, 0(a1) 200; RV64-NEXT: ret 201; 202; RV32ZBA-LABEL: saddo4.i32: 203; RV32ZBA: # %bb.0: # %entry 204; RV32ZBA-NEXT: lui a2, 4096 205; RV32ZBA-NEXT: addi a2, a2, -1 206; RV32ZBA-NEXT: add a2, a0, a2 207; RV32ZBA-NEXT: slt a0, a2, a0 208; RV32ZBA-NEXT: sw a2, 0(a1) 209; RV32ZBA-NEXT: ret 210; 211; RV64ZBA-LABEL: saddo4.i32: 212; RV64ZBA: # %bb.0: # %entry 213; RV64ZBA-NEXT: lui a2, 4096 214; RV64ZBA-NEXT: addi a2, a2, -1 215; RV64ZBA-NEXT: addw a2, a0, a2 216; RV64ZBA-NEXT: slt a0, a2, a0 217; RV64ZBA-NEXT: sw a2, 0(a1) 218; RV64ZBA-NEXT: ret 219; 220; RV32ZICOND-LABEL: saddo4.i32: 221; RV32ZICOND: # %bb.0: # %entry 222; RV32ZICOND-NEXT: lui a2, 4096 223; RV32ZICOND-NEXT: addi a2, a2, -1 224; RV32ZICOND-NEXT: add a2, a0, a2 225; RV32ZICOND-NEXT: slt a0, a2, a0 226; RV32ZICOND-NEXT: sw a2, 0(a1) 227; RV32ZICOND-NEXT: ret 228; 229; RV64ZICOND-LABEL: saddo4.i32: 230; RV64ZICOND: # %bb.0: # %entry 231; RV64ZICOND-NEXT: lui a2, 4096 232; RV64ZICOND-NEXT: addi a2, a2, -1 233; RV64ZICOND-NEXT: addw a2, a0, a2 234; RV64ZICOND-NEXT: slt a0, a2, a0 235; RV64ZICOND-NEXT: sw a2, 0(a1) 236; RV64ZICOND-NEXT: ret 237entry: 238 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 16777215) 239 %val = extractvalue {i32, i1} %t, 0 240 %obit = extractvalue {i32, i1} %t, 1 241 store i32 %val, ptr %res 242 ret i1 %obit 243} 244 245define zeroext i1 @saddo1.i64(i64 %v1, i64 %v2, ptr %res) { 246; RV32-LABEL: saddo1.i64: 247; RV32: # %bb.0: # %entry 248; RV32-NEXT: add a5, a1, a3 249; RV32-NEXT: add a2, a0, a2 250; RV32-NEXT: xor a3, a1, a3 251; RV32-NEXT: sltu a0, a2, a0 252; RV32-NEXT: not a3, a3 253; RV32-NEXT: add a5, a5, a0 254; RV32-NEXT: xor a1, a1, a5 255; RV32-NEXT: and a1, a3, a1 256; RV32-NEXT: slti a0, a1, 0 257; RV32-NEXT: sw a2, 0(a4) 258; RV32-NEXT: sw a5, 4(a4) 259; RV32-NEXT: ret 260; 261; RV64-LABEL: saddo1.i64: 262; RV64: # %bb.0: # %entry 263; RV64-NEXT: add a3, a0, a1 264; RV64-NEXT: slt a0, a3, a0 265; RV64-NEXT: slti a1, a1, 0 266; RV64-NEXT: xor a0, a1, a0 267; RV64-NEXT: sd a3, 0(a2) 268; RV64-NEXT: ret 269; 270; RV32ZBA-LABEL: saddo1.i64: 271; RV32ZBA: # %bb.0: # %entry 272; RV32ZBA-NEXT: add a5, a1, a3 273; RV32ZBA-NEXT: add a2, a0, a2 274; RV32ZBA-NEXT: xor a3, a1, a3 275; RV32ZBA-NEXT: sltu a0, a2, a0 276; RV32ZBA-NEXT: not a3, a3 277; RV32ZBA-NEXT: add a5, a5, a0 278; RV32ZBA-NEXT: xor a1, a1, a5 279; RV32ZBA-NEXT: and a1, a3, a1 280; RV32ZBA-NEXT: slti a0, a1, 0 281; RV32ZBA-NEXT: sw a2, 0(a4) 282; RV32ZBA-NEXT: sw a5, 4(a4) 283; RV32ZBA-NEXT: ret 284; 285; RV64ZBA-LABEL: saddo1.i64: 286; RV64ZBA: # %bb.0: # %entry 287; RV64ZBA-NEXT: add a3, a0, a1 288; RV64ZBA-NEXT: slt a0, a3, a0 289; RV64ZBA-NEXT: slti a1, a1, 0 290; RV64ZBA-NEXT: xor a0, a1, a0 291; RV64ZBA-NEXT: sd a3, 0(a2) 292; RV64ZBA-NEXT: ret 293; 294; RV32ZICOND-LABEL: saddo1.i64: 295; RV32ZICOND: # %bb.0: # %entry 296; RV32ZICOND-NEXT: add a5, a1, a3 297; RV32ZICOND-NEXT: add a2, a0, a2 298; RV32ZICOND-NEXT: xor a3, a1, a3 299; RV32ZICOND-NEXT: sltu a0, a2, a0 300; RV32ZICOND-NEXT: not a3, a3 301; RV32ZICOND-NEXT: add a5, a5, a0 302; RV32ZICOND-NEXT: xor a1, a1, a5 303; RV32ZICOND-NEXT: and a1, a3, a1 304; RV32ZICOND-NEXT: slti a0, a1, 0 305; RV32ZICOND-NEXT: sw a2, 0(a4) 306; RV32ZICOND-NEXT: sw a5, 4(a4) 307; RV32ZICOND-NEXT: ret 308; 309; RV64ZICOND-LABEL: saddo1.i64: 310; RV64ZICOND: # %bb.0: # %entry 311; RV64ZICOND-NEXT: add a3, a0, a1 312; RV64ZICOND-NEXT: slt a0, a3, a0 313; RV64ZICOND-NEXT: slti a1, a1, 0 314; RV64ZICOND-NEXT: xor a0, a1, a0 315; RV64ZICOND-NEXT: sd a3, 0(a2) 316; RV64ZICOND-NEXT: ret 317entry: 318 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2) 319 %val = extractvalue {i64, i1} %t, 0 320 %obit = extractvalue {i64, i1} %t, 1 321 store i64 %val, ptr %res 322 ret i1 %obit 323} 324 325define zeroext i1 @saddo2.i64(i64 %v1, ptr %res) { 326; RV32-LABEL: saddo2.i64: 327; RV32: # %bb.0: # %entry 328; RV32-NEXT: addi a3, a0, 4 329; RV32-NEXT: not a4, a1 330; RV32-NEXT: sltu a0, a3, a0 331; RV32-NEXT: add a5, a1, a0 332; RV32-NEXT: xor a1, a1, a5 333; RV32-NEXT: and a1, a4, a1 334; RV32-NEXT: slti a0, a1, 0 335; RV32-NEXT: sw a3, 0(a2) 336; RV32-NEXT: sw a5, 4(a2) 337; RV32-NEXT: ret 338; 339; RV64-LABEL: saddo2.i64: 340; RV64: # %bb.0: # %entry 341; RV64-NEXT: addi a2, a0, 4 342; RV64-NEXT: slt a0, a2, a0 343; RV64-NEXT: sd a2, 0(a1) 344; RV64-NEXT: ret 345; 346; RV32ZBA-LABEL: saddo2.i64: 347; RV32ZBA: # %bb.0: # %entry 348; RV32ZBA-NEXT: addi a3, a0, 4 349; RV32ZBA-NEXT: not a4, a1 350; RV32ZBA-NEXT: sltu a0, a3, a0 351; RV32ZBA-NEXT: add a5, a1, a0 352; RV32ZBA-NEXT: xor a1, a1, a5 353; RV32ZBA-NEXT: and a1, a4, a1 354; RV32ZBA-NEXT: slti a0, a1, 0 355; RV32ZBA-NEXT: sw a3, 0(a2) 356; RV32ZBA-NEXT: sw a5, 4(a2) 357; RV32ZBA-NEXT: ret 358; 359; RV64ZBA-LABEL: saddo2.i64: 360; RV64ZBA: # %bb.0: # %entry 361; RV64ZBA-NEXT: addi a2, a0, 4 362; RV64ZBA-NEXT: slt a0, a2, a0 363; RV64ZBA-NEXT: sd a2, 0(a1) 364; RV64ZBA-NEXT: ret 365; 366; RV32ZICOND-LABEL: saddo2.i64: 367; RV32ZICOND: # %bb.0: # %entry 368; RV32ZICOND-NEXT: addi a3, a0, 4 369; RV32ZICOND-NEXT: not a4, a1 370; RV32ZICOND-NEXT: sltu a0, a3, a0 371; RV32ZICOND-NEXT: add a5, a1, a0 372; RV32ZICOND-NEXT: xor a1, a1, a5 373; RV32ZICOND-NEXT: and a1, a4, a1 374; RV32ZICOND-NEXT: slti a0, a1, 0 375; RV32ZICOND-NEXT: sw a3, 0(a2) 376; RV32ZICOND-NEXT: sw a5, 4(a2) 377; RV32ZICOND-NEXT: ret 378; 379; RV64ZICOND-LABEL: saddo2.i64: 380; RV64ZICOND: # %bb.0: # %entry 381; RV64ZICOND-NEXT: addi a2, a0, 4 382; RV64ZICOND-NEXT: slt a0, a2, a0 383; RV64ZICOND-NEXT: sd a2, 0(a1) 384; RV64ZICOND-NEXT: ret 385entry: 386 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 4) 387 %val = extractvalue {i64, i1} %t, 0 388 %obit = extractvalue {i64, i1} %t, 1 389 store i64 %val, ptr %res 390 ret i1 %obit 391} 392 393define zeroext i1 @saddo3.i64(i64 %v1, ptr %res) { 394; RV32-LABEL: saddo3.i64: 395; RV32: # %bb.0: # %entry 396; RV32-NEXT: addi a3, a0, -4 397; RV32-NEXT: sltu a0, a3, a0 398; RV32-NEXT: add a0, a1, a0 399; RV32-NEXT: addi a4, a0, -1 400; RV32-NEXT: xor a0, a1, a4 401; RV32-NEXT: and a0, a1, a0 402; RV32-NEXT: slti a0, a0, 0 403; RV32-NEXT: sw a3, 0(a2) 404; RV32-NEXT: sw a4, 4(a2) 405; RV32-NEXT: ret 406; 407; RV64-LABEL: saddo3.i64: 408; RV64: # %bb.0: # %entry 409; RV64-NEXT: addi a2, a0, -4 410; RV64-NEXT: slt a0, a2, a0 411; RV64-NEXT: xori a0, a0, 1 412; RV64-NEXT: sd a2, 0(a1) 413; RV64-NEXT: ret 414; 415; RV32ZBA-LABEL: saddo3.i64: 416; RV32ZBA: # %bb.0: # %entry 417; RV32ZBA-NEXT: addi a3, a0, -4 418; RV32ZBA-NEXT: sltu a0, a3, a0 419; RV32ZBA-NEXT: add a0, a1, a0 420; RV32ZBA-NEXT: addi a4, a0, -1 421; RV32ZBA-NEXT: xor a0, a1, a4 422; RV32ZBA-NEXT: and a0, a1, a0 423; RV32ZBA-NEXT: slti a0, a0, 0 424; RV32ZBA-NEXT: sw a3, 0(a2) 425; RV32ZBA-NEXT: sw a4, 4(a2) 426; RV32ZBA-NEXT: ret 427; 428; RV64ZBA-LABEL: saddo3.i64: 429; RV64ZBA: # %bb.0: # %entry 430; RV64ZBA-NEXT: addi a2, a0, -4 431; RV64ZBA-NEXT: slt a0, a2, a0 432; RV64ZBA-NEXT: xori a0, a0, 1 433; RV64ZBA-NEXT: sd a2, 0(a1) 434; RV64ZBA-NEXT: ret 435; 436; RV32ZICOND-LABEL: saddo3.i64: 437; RV32ZICOND: # %bb.0: # %entry 438; RV32ZICOND-NEXT: addi a3, a0, -4 439; RV32ZICOND-NEXT: sltu a0, a3, a0 440; RV32ZICOND-NEXT: add a0, a1, a0 441; RV32ZICOND-NEXT: addi a4, a0, -1 442; RV32ZICOND-NEXT: xor a0, a1, a4 443; RV32ZICOND-NEXT: and a0, a1, a0 444; RV32ZICOND-NEXT: slti a0, a0, 0 445; RV32ZICOND-NEXT: sw a3, 0(a2) 446; RV32ZICOND-NEXT: sw a4, 4(a2) 447; RV32ZICOND-NEXT: ret 448; 449; RV64ZICOND-LABEL: saddo3.i64: 450; RV64ZICOND: # %bb.0: # %entry 451; RV64ZICOND-NEXT: addi a2, a0, -4 452; RV64ZICOND-NEXT: slt a0, a2, a0 453; RV64ZICOND-NEXT: xori a0, a0, 1 454; RV64ZICOND-NEXT: sd a2, 0(a1) 455; RV64ZICOND-NEXT: ret 456entry: 457 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 -4) 458 %val = extractvalue {i64, i1} %t, 0 459 %obit = extractvalue {i64, i1} %t, 1 460 store i64 %val, ptr %res 461 ret i1 %obit 462} 463 464define zeroext i1 @uaddo.i32(i32 signext %v1, i32 signext %v2, ptr %res) { 465; RV32-LABEL: uaddo.i32: 466; RV32: # %bb.0: # %entry 467; RV32-NEXT: add a1, a0, a1 468; RV32-NEXT: sltu a0, a1, a0 469; RV32-NEXT: sw a1, 0(a2) 470; RV32-NEXT: ret 471; 472; RV64-LABEL: uaddo.i32: 473; RV64: # %bb.0: # %entry 474; RV64-NEXT: addw a1, a0, a1 475; RV64-NEXT: sltu a0, a1, a0 476; RV64-NEXT: sw a1, 0(a2) 477; RV64-NEXT: ret 478; 479; RV32ZBA-LABEL: uaddo.i32: 480; RV32ZBA: # %bb.0: # %entry 481; RV32ZBA-NEXT: add a1, a0, a1 482; RV32ZBA-NEXT: sltu a0, a1, a0 483; RV32ZBA-NEXT: sw a1, 0(a2) 484; RV32ZBA-NEXT: ret 485; 486; RV64ZBA-LABEL: uaddo.i32: 487; RV64ZBA: # %bb.0: # %entry 488; RV64ZBA-NEXT: addw a1, a0, a1 489; RV64ZBA-NEXT: sltu a0, a1, a0 490; RV64ZBA-NEXT: sw a1, 0(a2) 491; RV64ZBA-NEXT: ret 492; 493; RV32ZICOND-LABEL: uaddo.i32: 494; RV32ZICOND: # %bb.0: # %entry 495; RV32ZICOND-NEXT: add a1, a0, a1 496; RV32ZICOND-NEXT: sltu a0, a1, a0 497; RV32ZICOND-NEXT: sw a1, 0(a2) 498; RV32ZICOND-NEXT: ret 499; 500; RV64ZICOND-LABEL: uaddo.i32: 501; RV64ZICOND: # %bb.0: # %entry 502; RV64ZICOND-NEXT: addw a1, a0, a1 503; RV64ZICOND-NEXT: sltu a0, a1, a0 504; RV64ZICOND-NEXT: sw a1, 0(a2) 505; RV64ZICOND-NEXT: ret 506entry: 507 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2) 508 %val = extractvalue {i32, i1} %t, 0 509 %obit = extractvalue {i32, i1} %t, 1 510 store i32 %val, ptr %res 511 ret i1 %obit 512} 513 514define zeroext i1 @uaddo.i32.constant(i32 signext %v1, ptr %res) { 515; RV32-LABEL: uaddo.i32.constant: 516; RV32: # %bb.0: # %entry 517; RV32-NEXT: addi a2, a0, -2 518; RV32-NEXT: sltu a0, a2, a0 519; RV32-NEXT: sw a2, 0(a1) 520; RV32-NEXT: ret 521; 522; RV64-LABEL: uaddo.i32.constant: 523; RV64: # %bb.0: # %entry 524; RV64-NEXT: addiw a2, a0, -2 525; RV64-NEXT: sltu a0, a2, a0 526; RV64-NEXT: sw a2, 0(a1) 527; RV64-NEXT: ret 528; 529; RV32ZBA-LABEL: uaddo.i32.constant: 530; RV32ZBA: # %bb.0: # %entry 531; RV32ZBA-NEXT: addi a2, a0, -2 532; RV32ZBA-NEXT: sltu a0, a2, a0 533; RV32ZBA-NEXT: sw a2, 0(a1) 534; RV32ZBA-NEXT: ret 535; 536; RV64ZBA-LABEL: uaddo.i32.constant: 537; RV64ZBA: # %bb.0: # %entry 538; RV64ZBA-NEXT: addiw a2, a0, -2 539; RV64ZBA-NEXT: sltu a0, a2, a0 540; RV64ZBA-NEXT: sw a2, 0(a1) 541; RV64ZBA-NEXT: ret 542; 543; RV32ZICOND-LABEL: uaddo.i32.constant: 544; RV32ZICOND: # %bb.0: # %entry 545; RV32ZICOND-NEXT: addi a2, a0, -2 546; RV32ZICOND-NEXT: sltu a0, a2, a0 547; RV32ZICOND-NEXT: sw a2, 0(a1) 548; RV32ZICOND-NEXT: ret 549; 550; RV64ZICOND-LABEL: uaddo.i32.constant: 551; RV64ZICOND: # %bb.0: # %entry 552; RV64ZICOND-NEXT: addiw a2, a0, -2 553; RV64ZICOND-NEXT: sltu a0, a2, a0 554; RV64ZICOND-NEXT: sw a2, 0(a1) 555; RV64ZICOND-NEXT: ret 556entry: 557 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 -2) 558 %val = extractvalue {i32, i1} %t, 0 559 %obit = extractvalue {i32, i1} %t, 1 560 store i32 %val, ptr %res 561 ret i1 %obit 562} 563 564define zeroext i1 @uaddo.i32.constant_one(i32 signext %v1, ptr %res) { 565; RV32-LABEL: uaddo.i32.constant_one: 566; RV32: # %bb.0: # %entry 567; RV32-NEXT: addi a2, a0, 1 568; RV32-NEXT: seqz a0, a2 569; RV32-NEXT: sw a2, 0(a1) 570; RV32-NEXT: ret 571; 572; RV64-LABEL: uaddo.i32.constant_one: 573; RV64: # %bb.0: # %entry 574; RV64-NEXT: addiw a2, a0, 1 575; RV64-NEXT: seqz a0, a2 576; RV64-NEXT: sw a2, 0(a1) 577; RV64-NEXT: ret 578; 579; RV32ZBA-LABEL: uaddo.i32.constant_one: 580; RV32ZBA: # %bb.0: # %entry 581; RV32ZBA-NEXT: addi a2, a0, 1 582; RV32ZBA-NEXT: seqz a0, a2 583; RV32ZBA-NEXT: sw a2, 0(a1) 584; RV32ZBA-NEXT: ret 585; 586; RV64ZBA-LABEL: uaddo.i32.constant_one: 587; RV64ZBA: # %bb.0: # %entry 588; RV64ZBA-NEXT: addiw a2, a0, 1 589; RV64ZBA-NEXT: seqz a0, a2 590; RV64ZBA-NEXT: sw a2, 0(a1) 591; RV64ZBA-NEXT: ret 592; 593; RV32ZICOND-LABEL: uaddo.i32.constant_one: 594; RV32ZICOND: # %bb.0: # %entry 595; RV32ZICOND-NEXT: addi a2, a0, 1 596; RV32ZICOND-NEXT: seqz a0, a2 597; RV32ZICOND-NEXT: sw a2, 0(a1) 598; RV32ZICOND-NEXT: ret 599; 600; RV64ZICOND-LABEL: uaddo.i32.constant_one: 601; RV64ZICOND: # %bb.0: # %entry 602; RV64ZICOND-NEXT: addiw a2, a0, 1 603; RV64ZICOND-NEXT: seqz a0, a2 604; RV64ZICOND-NEXT: sw a2, 0(a1) 605; RV64ZICOND-NEXT: ret 606entry: 607 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 1) 608 %val = extractvalue {i32, i1} %t, 0 609 %obit = extractvalue {i32, i1} %t, 1 610 store i32 %val, ptr %res 611 ret i1 %obit 612} 613 614define zeroext i1 @uaddo.i64(i64 %v1, i64 %v2, ptr %res) { 615; RV32-LABEL: uaddo.i64: 616; RV32: # %bb.0: # %entry 617; RV32-NEXT: add a3, a1, a3 618; RV32-NEXT: add a2, a0, a2 619; RV32-NEXT: sltu a0, a2, a0 620; RV32-NEXT: add a3, a3, a0 621; RV32-NEXT: beq a3, a1, .LBB10_2 622; RV32-NEXT: # %bb.1: # %entry 623; RV32-NEXT: sltu a0, a3, a1 624; RV32-NEXT: .LBB10_2: # %entry 625; RV32-NEXT: sw a2, 0(a4) 626; RV32-NEXT: sw a3, 4(a4) 627; RV32-NEXT: ret 628; 629; RV64-LABEL: uaddo.i64: 630; RV64: # %bb.0: # %entry 631; RV64-NEXT: add a1, a0, a1 632; RV64-NEXT: sltu a0, a1, a0 633; RV64-NEXT: sd a1, 0(a2) 634; RV64-NEXT: ret 635; 636; RV32ZBA-LABEL: uaddo.i64: 637; RV32ZBA: # %bb.0: # %entry 638; RV32ZBA-NEXT: add a3, a1, a3 639; RV32ZBA-NEXT: add a2, a0, a2 640; RV32ZBA-NEXT: sltu a0, a2, a0 641; RV32ZBA-NEXT: add a3, a3, a0 642; RV32ZBA-NEXT: beq a3, a1, .LBB10_2 643; RV32ZBA-NEXT: # %bb.1: # %entry 644; RV32ZBA-NEXT: sltu a0, a3, a1 645; RV32ZBA-NEXT: .LBB10_2: # %entry 646; RV32ZBA-NEXT: sw a2, 0(a4) 647; RV32ZBA-NEXT: sw a3, 4(a4) 648; RV32ZBA-NEXT: ret 649; 650; RV64ZBA-LABEL: uaddo.i64: 651; RV64ZBA: # %bb.0: # %entry 652; RV64ZBA-NEXT: add a1, a0, a1 653; RV64ZBA-NEXT: sltu a0, a1, a0 654; RV64ZBA-NEXT: sd a1, 0(a2) 655; RV64ZBA-NEXT: ret 656; 657; RV32ZICOND-LABEL: uaddo.i64: 658; RV32ZICOND: # %bb.0: # %entry 659; RV32ZICOND-NEXT: add a3, a1, a3 660; RV32ZICOND-NEXT: add a2, a0, a2 661; RV32ZICOND-NEXT: sltu a0, a2, a0 662; RV32ZICOND-NEXT: add a3, a3, a0 663; RV32ZICOND-NEXT: xor a5, a3, a1 664; RV32ZICOND-NEXT: sltu a1, a3, a1 665; RV32ZICOND-NEXT: czero.eqz a1, a1, a5 666; RV32ZICOND-NEXT: czero.nez a0, a0, a5 667; RV32ZICOND-NEXT: or a0, a0, a1 668; RV32ZICOND-NEXT: sw a2, 0(a4) 669; RV32ZICOND-NEXT: sw a3, 4(a4) 670; RV32ZICOND-NEXT: ret 671; 672; RV64ZICOND-LABEL: uaddo.i64: 673; RV64ZICOND: # %bb.0: # %entry 674; RV64ZICOND-NEXT: add a1, a0, a1 675; RV64ZICOND-NEXT: sltu a0, a1, a0 676; RV64ZICOND-NEXT: sd a1, 0(a2) 677; RV64ZICOND-NEXT: ret 678entry: 679 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2) 680 %val = extractvalue {i64, i1} %t, 0 681 %obit = extractvalue {i64, i1} %t, 1 682 store i64 %val, ptr %res 683 ret i1 %obit 684} 685 686define zeroext i1 @uaddo.i64.constant_one(i64 %v1, ptr %res) { 687; RV32-LABEL: uaddo.i64.constant_one: 688; RV32: # %bb.0: # %entry 689; RV32-NEXT: addi a3, a0, 1 690; RV32-NEXT: seqz a0, a3 691; RV32-NEXT: add a1, a1, a0 692; RV32-NEXT: or a0, a3, a1 693; RV32-NEXT: seqz a0, a0 694; RV32-NEXT: sw a3, 0(a2) 695; RV32-NEXT: sw a1, 4(a2) 696; RV32-NEXT: ret 697; 698; RV64-LABEL: uaddo.i64.constant_one: 699; RV64: # %bb.0: # %entry 700; RV64-NEXT: addi a2, a0, 1 701; RV64-NEXT: seqz a0, a2 702; RV64-NEXT: sd a2, 0(a1) 703; RV64-NEXT: ret 704; 705; RV32ZBA-LABEL: uaddo.i64.constant_one: 706; RV32ZBA: # %bb.0: # %entry 707; RV32ZBA-NEXT: addi a3, a0, 1 708; RV32ZBA-NEXT: seqz a0, a3 709; RV32ZBA-NEXT: add a1, a1, a0 710; RV32ZBA-NEXT: or a0, a3, a1 711; RV32ZBA-NEXT: seqz a0, a0 712; RV32ZBA-NEXT: sw a3, 0(a2) 713; RV32ZBA-NEXT: sw a1, 4(a2) 714; RV32ZBA-NEXT: ret 715; 716; RV64ZBA-LABEL: uaddo.i64.constant_one: 717; RV64ZBA: # %bb.0: # %entry 718; RV64ZBA-NEXT: addi a2, a0, 1 719; RV64ZBA-NEXT: seqz a0, a2 720; RV64ZBA-NEXT: sd a2, 0(a1) 721; RV64ZBA-NEXT: ret 722; 723; RV32ZICOND-LABEL: uaddo.i64.constant_one: 724; RV32ZICOND: # %bb.0: # %entry 725; RV32ZICOND-NEXT: addi a3, a0, 1 726; RV32ZICOND-NEXT: seqz a0, a3 727; RV32ZICOND-NEXT: add a1, a1, a0 728; RV32ZICOND-NEXT: or a0, a3, a1 729; RV32ZICOND-NEXT: seqz a0, a0 730; RV32ZICOND-NEXT: sw a3, 0(a2) 731; RV32ZICOND-NEXT: sw a1, 4(a2) 732; RV32ZICOND-NEXT: ret 733; 734; RV64ZICOND-LABEL: uaddo.i64.constant_one: 735; RV64ZICOND: # %bb.0: # %entry 736; RV64ZICOND-NEXT: addi a2, a0, 1 737; RV64ZICOND-NEXT: seqz a0, a2 738; RV64ZICOND-NEXT: sd a2, 0(a1) 739; RV64ZICOND-NEXT: ret 740entry: 741 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 1) 742 %val = extractvalue {i64, i1} %t, 0 743 %obit = extractvalue {i64, i1} %t, 1 744 store i64 %val, ptr %res 745 ret i1 %obit 746} 747 748define zeroext i1 @ssubo1.i32(i32 signext %v1, i32 signext %v2, ptr %res) { 749; RV32-LABEL: ssubo1.i32: 750; RV32: # %bb.0: # %entry 751; RV32-NEXT: sgtz a3, a1 752; RV32-NEXT: sub a1, a0, a1 753; RV32-NEXT: slt a0, a1, a0 754; RV32-NEXT: xor a0, a3, a0 755; RV32-NEXT: sw a1, 0(a2) 756; RV32-NEXT: ret 757; 758; RV64-LABEL: ssubo1.i32: 759; RV64: # %bb.0: # %entry 760; RV64-NEXT: sub a3, a0, a1 761; RV64-NEXT: subw a0, a0, a1 762; RV64-NEXT: xor a0, a0, a3 763; RV64-NEXT: snez a0, a0 764; RV64-NEXT: sw a3, 0(a2) 765; RV64-NEXT: ret 766; 767; RV32ZBA-LABEL: ssubo1.i32: 768; RV32ZBA: # %bb.0: # %entry 769; RV32ZBA-NEXT: sgtz a3, a1 770; RV32ZBA-NEXT: sub a1, a0, a1 771; RV32ZBA-NEXT: slt a0, a1, a0 772; RV32ZBA-NEXT: xor a0, a3, a0 773; RV32ZBA-NEXT: sw a1, 0(a2) 774; RV32ZBA-NEXT: ret 775; 776; RV64ZBA-LABEL: ssubo1.i32: 777; RV64ZBA: # %bb.0: # %entry 778; RV64ZBA-NEXT: sub a3, a0, a1 779; RV64ZBA-NEXT: subw a0, a0, a1 780; RV64ZBA-NEXT: xor a0, a0, a3 781; RV64ZBA-NEXT: snez a0, a0 782; RV64ZBA-NEXT: sw a3, 0(a2) 783; RV64ZBA-NEXT: ret 784; 785; RV32ZICOND-LABEL: ssubo1.i32: 786; RV32ZICOND: # %bb.0: # %entry 787; RV32ZICOND-NEXT: sgtz a3, a1 788; RV32ZICOND-NEXT: sub a1, a0, a1 789; RV32ZICOND-NEXT: slt a0, a1, a0 790; RV32ZICOND-NEXT: xor a0, a3, a0 791; RV32ZICOND-NEXT: sw a1, 0(a2) 792; RV32ZICOND-NEXT: ret 793; 794; RV64ZICOND-LABEL: ssubo1.i32: 795; RV64ZICOND: # %bb.0: # %entry 796; RV64ZICOND-NEXT: sub a3, a0, a1 797; RV64ZICOND-NEXT: subw a0, a0, a1 798; RV64ZICOND-NEXT: xor a0, a0, a3 799; RV64ZICOND-NEXT: snez a0, a0 800; RV64ZICOND-NEXT: sw a3, 0(a2) 801; RV64ZICOND-NEXT: ret 802entry: 803 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2) 804 %val = extractvalue {i32, i1} %t, 0 805 %obit = extractvalue {i32, i1} %t, 1 806 store i32 %val, ptr %res 807 ret i1 %obit 808} 809 810define zeroext i1 @ssubo2.i32(i32 signext %v1, ptr %res) { 811; RV32-LABEL: ssubo2.i32: 812; RV32: # %bb.0: # %entry 813; RV32-NEXT: addi a2, a0, 4 814; RV32-NEXT: slt a0, a2, a0 815; RV32-NEXT: sw a2, 0(a1) 816; RV32-NEXT: ret 817; 818; RV64-LABEL: ssubo2.i32: 819; RV64: # %bb.0: # %entry 820; RV64-NEXT: addiw a2, a0, 4 821; RV64-NEXT: slt a0, a2, a0 822; RV64-NEXT: sw a2, 0(a1) 823; RV64-NEXT: ret 824; 825; RV32ZBA-LABEL: ssubo2.i32: 826; RV32ZBA: # %bb.0: # %entry 827; RV32ZBA-NEXT: addi a2, a0, 4 828; RV32ZBA-NEXT: slt a0, a2, a0 829; RV32ZBA-NEXT: sw a2, 0(a1) 830; RV32ZBA-NEXT: ret 831; 832; RV64ZBA-LABEL: ssubo2.i32: 833; RV64ZBA: # %bb.0: # %entry 834; RV64ZBA-NEXT: addiw a2, a0, 4 835; RV64ZBA-NEXT: slt a0, a2, a0 836; RV64ZBA-NEXT: sw a2, 0(a1) 837; RV64ZBA-NEXT: ret 838; 839; RV32ZICOND-LABEL: ssubo2.i32: 840; RV32ZICOND: # %bb.0: # %entry 841; RV32ZICOND-NEXT: addi a2, a0, 4 842; RV32ZICOND-NEXT: slt a0, a2, a0 843; RV32ZICOND-NEXT: sw a2, 0(a1) 844; RV32ZICOND-NEXT: ret 845; 846; RV64ZICOND-LABEL: ssubo2.i32: 847; RV64ZICOND: # %bb.0: # %entry 848; RV64ZICOND-NEXT: addiw a2, a0, 4 849; RV64ZICOND-NEXT: slt a0, a2, a0 850; RV64ZICOND-NEXT: sw a2, 0(a1) 851; RV64ZICOND-NEXT: ret 852entry: 853 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 -4) 854 %val = extractvalue {i32, i1} %t, 0 855 %obit = extractvalue {i32, i1} %t, 1 856 store i32 %val, ptr %res 857 ret i1 %obit 858} 859 860define zeroext i1 @ssubo.i64(i64 %v1, i64 %v2, ptr %res) { 861; RV32-LABEL: ssubo.i64: 862; RV32: # %bb.0: # %entry 863; RV32-NEXT: sltu a5, a0, a2 864; RV32-NEXT: sub a6, a1, a3 865; RV32-NEXT: xor a3, a1, a3 866; RV32-NEXT: sub a2, a0, a2 867; RV32-NEXT: sub a5, a6, a5 868; RV32-NEXT: xor a1, a1, a5 869; RV32-NEXT: and a1, a3, a1 870; RV32-NEXT: slti a0, a1, 0 871; RV32-NEXT: sw a2, 0(a4) 872; RV32-NEXT: sw a5, 4(a4) 873; RV32-NEXT: ret 874; 875; RV64-LABEL: ssubo.i64: 876; RV64: # %bb.0: # %entry 877; RV64-NEXT: sgtz a3, a1 878; RV64-NEXT: sub a1, a0, a1 879; RV64-NEXT: slt a0, a1, a0 880; RV64-NEXT: xor a0, a3, a0 881; RV64-NEXT: sd a1, 0(a2) 882; RV64-NEXT: ret 883; 884; RV32ZBA-LABEL: ssubo.i64: 885; RV32ZBA: # %bb.0: # %entry 886; RV32ZBA-NEXT: sltu a5, a0, a2 887; RV32ZBA-NEXT: sub a6, a1, a3 888; RV32ZBA-NEXT: xor a3, a1, a3 889; RV32ZBA-NEXT: sub a2, a0, a2 890; RV32ZBA-NEXT: sub a5, a6, a5 891; RV32ZBA-NEXT: xor a1, a1, a5 892; RV32ZBA-NEXT: and a1, a3, a1 893; RV32ZBA-NEXT: slti a0, a1, 0 894; RV32ZBA-NEXT: sw a2, 0(a4) 895; RV32ZBA-NEXT: sw a5, 4(a4) 896; RV32ZBA-NEXT: ret 897; 898; RV64ZBA-LABEL: ssubo.i64: 899; RV64ZBA: # %bb.0: # %entry 900; RV64ZBA-NEXT: sgtz a3, a1 901; RV64ZBA-NEXT: sub a1, a0, a1 902; RV64ZBA-NEXT: slt a0, a1, a0 903; RV64ZBA-NEXT: xor a0, a3, a0 904; RV64ZBA-NEXT: sd a1, 0(a2) 905; RV64ZBA-NEXT: ret 906; 907; RV32ZICOND-LABEL: ssubo.i64: 908; RV32ZICOND: # %bb.0: # %entry 909; RV32ZICOND-NEXT: sltu a5, a0, a2 910; RV32ZICOND-NEXT: sub a6, a1, a3 911; RV32ZICOND-NEXT: xor a3, a1, a3 912; RV32ZICOND-NEXT: sub a2, a0, a2 913; RV32ZICOND-NEXT: sub a5, a6, a5 914; RV32ZICOND-NEXT: xor a1, a1, a5 915; RV32ZICOND-NEXT: and a1, a3, a1 916; RV32ZICOND-NEXT: slti a0, a1, 0 917; RV32ZICOND-NEXT: sw a2, 0(a4) 918; RV32ZICOND-NEXT: sw a5, 4(a4) 919; RV32ZICOND-NEXT: ret 920; 921; RV64ZICOND-LABEL: ssubo.i64: 922; RV64ZICOND: # %bb.0: # %entry 923; RV64ZICOND-NEXT: sgtz a3, a1 924; RV64ZICOND-NEXT: sub a1, a0, a1 925; RV64ZICOND-NEXT: slt a0, a1, a0 926; RV64ZICOND-NEXT: xor a0, a3, a0 927; RV64ZICOND-NEXT: sd a1, 0(a2) 928; RV64ZICOND-NEXT: ret 929entry: 930 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2) 931 %val = extractvalue {i64, i1} %t, 0 932 %obit = extractvalue {i64, i1} %t, 1 933 store i64 %val, ptr %res 934 ret i1 %obit 935} 936 937define zeroext i1 @usubo.i32(i32 signext %v1, i32 signext %v2, ptr %res) { 938; RV32-LABEL: usubo.i32: 939; RV32: # %bb.0: # %entry 940; RV32-NEXT: sub a1, a0, a1 941; RV32-NEXT: sltu a0, a0, a1 942; RV32-NEXT: sw a1, 0(a2) 943; RV32-NEXT: ret 944; 945; RV64-LABEL: usubo.i32: 946; RV64: # %bb.0: # %entry 947; RV64-NEXT: subw a1, a0, a1 948; RV64-NEXT: sltu a0, a0, a1 949; RV64-NEXT: sw a1, 0(a2) 950; RV64-NEXT: ret 951; 952; RV32ZBA-LABEL: usubo.i32: 953; RV32ZBA: # %bb.0: # %entry 954; RV32ZBA-NEXT: sub a1, a0, a1 955; RV32ZBA-NEXT: sltu a0, a0, a1 956; RV32ZBA-NEXT: sw a1, 0(a2) 957; RV32ZBA-NEXT: ret 958; 959; RV64ZBA-LABEL: usubo.i32: 960; RV64ZBA: # %bb.0: # %entry 961; RV64ZBA-NEXT: subw a1, a0, a1 962; RV64ZBA-NEXT: sltu a0, a0, a1 963; RV64ZBA-NEXT: sw a1, 0(a2) 964; RV64ZBA-NEXT: ret 965; 966; RV32ZICOND-LABEL: usubo.i32: 967; RV32ZICOND: # %bb.0: # %entry 968; RV32ZICOND-NEXT: sub a1, a0, a1 969; RV32ZICOND-NEXT: sltu a0, a0, a1 970; RV32ZICOND-NEXT: sw a1, 0(a2) 971; RV32ZICOND-NEXT: ret 972; 973; RV64ZICOND-LABEL: usubo.i32: 974; RV64ZICOND: # %bb.0: # %entry 975; RV64ZICOND-NEXT: subw a1, a0, a1 976; RV64ZICOND-NEXT: sltu a0, a0, a1 977; RV64ZICOND-NEXT: sw a1, 0(a2) 978; RV64ZICOND-NEXT: ret 979entry: 980 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2) 981 %val = extractvalue {i32, i1} %t, 0 982 %obit = extractvalue {i32, i1} %t, 1 983 store i32 %val, ptr %res 984 ret i1 %obit 985} 986 987define zeroext i1 @usubo.i32.constant.rhs(i32 signext %v1, ptr %res) { 988; RV32-LABEL: usubo.i32.constant.rhs: 989; RV32: # %bb.0: # %entry 990; RV32-NEXT: addi a2, a0, 2 991; RV32-NEXT: sltu a0, a0, a2 992; RV32-NEXT: sw a2, 0(a1) 993; RV32-NEXT: ret 994; 995; RV64-LABEL: usubo.i32.constant.rhs: 996; RV64: # %bb.0: # %entry 997; RV64-NEXT: addiw a2, a0, 2 998; RV64-NEXT: sltu a0, a0, a2 999; RV64-NEXT: sw a2, 0(a1) 1000; RV64-NEXT: ret 1001; 1002; RV32ZBA-LABEL: usubo.i32.constant.rhs: 1003; RV32ZBA: # %bb.0: # %entry 1004; RV32ZBA-NEXT: addi a2, a0, 2 1005; RV32ZBA-NEXT: sltu a0, a0, a2 1006; RV32ZBA-NEXT: sw a2, 0(a1) 1007; RV32ZBA-NEXT: ret 1008; 1009; RV64ZBA-LABEL: usubo.i32.constant.rhs: 1010; RV64ZBA: # %bb.0: # %entry 1011; RV64ZBA-NEXT: addiw a2, a0, 2 1012; RV64ZBA-NEXT: sltu a0, a0, a2 1013; RV64ZBA-NEXT: sw a2, 0(a1) 1014; RV64ZBA-NEXT: ret 1015; 1016; RV32ZICOND-LABEL: usubo.i32.constant.rhs: 1017; RV32ZICOND: # %bb.0: # %entry 1018; RV32ZICOND-NEXT: addi a2, a0, 2 1019; RV32ZICOND-NEXT: sltu a0, a0, a2 1020; RV32ZICOND-NEXT: sw a2, 0(a1) 1021; RV32ZICOND-NEXT: ret 1022; 1023; RV64ZICOND-LABEL: usubo.i32.constant.rhs: 1024; RV64ZICOND: # %bb.0: # %entry 1025; RV64ZICOND-NEXT: addiw a2, a0, 2 1026; RV64ZICOND-NEXT: sltu a0, a0, a2 1027; RV64ZICOND-NEXT: sw a2, 0(a1) 1028; RV64ZICOND-NEXT: ret 1029entry: 1030 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 -2) 1031 %val = extractvalue {i32, i1} %t, 0 1032 %obit = extractvalue {i32, i1} %t, 1 1033 store i32 %val, ptr %res 1034 ret i1 %obit 1035} 1036 1037define zeroext i1 @usubo.i32.constant.lhs(i32 signext %v1, ptr %res) { 1038; RV32-LABEL: usubo.i32.constant.lhs: 1039; RV32: # %bb.0: # %entry 1040; RV32-NEXT: li a2, -2 1041; RV32-NEXT: sub a2, a2, a0 1042; RV32-NEXT: addi a0, a2, 1 1043; RV32-NEXT: seqz a0, a0 1044; RV32-NEXT: sw a2, 0(a1) 1045; RV32-NEXT: ret 1046; 1047; RV64-LABEL: usubo.i32.constant.lhs: 1048; RV64: # %bb.0: # %entry 1049; RV64-NEXT: li a2, -2 1050; RV64-NEXT: subw a2, a2, a0 1051; RV64-NEXT: addi a0, a2, 1 1052; RV64-NEXT: seqz a0, a0 1053; RV64-NEXT: sw a2, 0(a1) 1054; RV64-NEXT: ret 1055; 1056; RV32ZBA-LABEL: usubo.i32.constant.lhs: 1057; RV32ZBA: # %bb.0: # %entry 1058; RV32ZBA-NEXT: li a2, -2 1059; RV32ZBA-NEXT: sub a2, a2, a0 1060; RV32ZBA-NEXT: addi a0, a2, 1 1061; RV32ZBA-NEXT: seqz a0, a0 1062; RV32ZBA-NEXT: sw a2, 0(a1) 1063; RV32ZBA-NEXT: ret 1064; 1065; RV64ZBA-LABEL: usubo.i32.constant.lhs: 1066; RV64ZBA: # %bb.0: # %entry 1067; RV64ZBA-NEXT: li a2, -2 1068; RV64ZBA-NEXT: subw a2, a2, a0 1069; RV64ZBA-NEXT: addi a0, a2, 1 1070; RV64ZBA-NEXT: seqz a0, a0 1071; RV64ZBA-NEXT: sw a2, 0(a1) 1072; RV64ZBA-NEXT: ret 1073; 1074; RV32ZICOND-LABEL: usubo.i32.constant.lhs: 1075; RV32ZICOND: # %bb.0: # %entry 1076; RV32ZICOND-NEXT: li a2, -2 1077; RV32ZICOND-NEXT: sub a2, a2, a0 1078; RV32ZICOND-NEXT: addi a0, a2, 1 1079; RV32ZICOND-NEXT: seqz a0, a0 1080; RV32ZICOND-NEXT: sw a2, 0(a1) 1081; RV32ZICOND-NEXT: ret 1082; 1083; RV64ZICOND-LABEL: usubo.i32.constant.lhs: 1084; RV64ZICOND: # %bb.0: # %entry 1085; RV64ZICOND-NEXT: li a2, -2 1086; RV64ZICOND-NEXT: subw a2, a2, a0 1087; RV64ZICOND-NEXT: addi a0, a2, 1 1088; RV64ZICOND-NEXT: seqz a0, a0 1089; RV64ZICOND-NEXT: sw a2, 0(a1) 1090; RV64ZICOND-NEXT: ret 1091entry: 1092 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 -2, i32 %v1) 1093 %val = extractvalue {i32, i1} %t, 0 1094 %obit = extractvalue {i32, i1} %t, 1 1095 store i32 %val, ptr %res 1096 ret i1 %obit 1097} 1098 1099define zeroext i1 @usubo.i64(i64 %v1, i64 %v2, ptr %res) { 1100; RV32-LABEL: usubo.i64: 1101; RV32: # %bb.0: # %entry 1102; RV32-NEXT: sltu a5, a0, a2 1103; RV32-NEXT: sub a3, a1, a3 1104; RV32-NEXT: sub a3, a3, a5 1105; RV32-NEXT: sub a2, a0, a2 1106; RV32-NEXT: beq a3, a1, .LBB18_2 1107; RV32-NEXT: # %bb.1: # %entry 1108; RV32-NEXT: sltu a0, a1, a3 1109; RV32-NEXT: j .LBB18_3 1110; RV32-NEXT: .LBB18_2: 1111; RV32-NEXT: sltu a0, a0, a2 1112; RV32-NEXT: .LBB18_3: # %entry 1113; RV32-NEXT: sw a2, 0(a4) 1114; RV32-NEXT: sw a3, 4(a4) 1115; RV32-NEXT: ret 1116; 1117; RV64-LABEL: usubo.i64: 1118; RV64: # %bb.0: # %entry 1119; RV64-NEXT: sub a1, a0, a1 1120; RV64-NEXT: sltu a0, a0, a1 1121; RV64-NEXT: sd a1, 0(a2) 1122; RV64-NEXT: ret 1123; 1124; RV32ZBA-LABEL: usubo.i64: 1125; RV32ZBA: # %bb.0: # %entry 1126; RV32ZBA-NEXT: sltu a5, a0, a2 1127; RV32ZBA-NEXT: sub a3, a1, a3 1128; RV32ZBA-NEXT: sub a3, a3, a5 1129; RV32ZBA-NEXT: sub a2, a0, a2 1130; RV32ZBA-NEXT: beq a3, a1, .LBB18_2 1131; RV32ZBA-NEXT: # %bb.1: # %entry 1132; RV32ZBA-NEXT: sltu a0, a1, a3 1133; RV32ZBA-NEXT: j .LBB18_3 1134; RV32ZBA-NEXT: .LBB18_2: 1135; RV32ZBA-NEXT: sltu a0, a0, a2 1136; RV32ZBA-NEXT: .LBB18_3: # %entry 1137; RV32ZBA-NEXT: sw a2, 0(a4) 1138; RV32ZBA-NEXT: sw a3, 4(a4) 1139; RV32ZBA-NEXT: ret 1140; 1141; RV64ZBA-LABEL: usubo.i64: 1142; RV64ZBA: # %bb.0: # %entry 1143; RV64ZBA-NEXT: sub a1, a0, a1 1144; RV64ZBA-NEXT: sltu a0, a0, a1 1145; RV64ZBA-NEXT: sd a1, 0(a2) 1146; RV64ZBA-NEXT: ret 1147; 1148; RV32ZICOND-LABEL: usubo.i64: 1149; RV32ZICOND: # %bb.0: # %entry 1150; RV32ZICOND-NEXT: sltu a5, a0, a2 1151; RV32ZICOND-NEXT: sub a3, a1, a3 1152; RV32ZICOND-NEXT: sub a2, a0, a2 1153; RV32ZICOND-NEXT: sub a3, a3, a5 1154; RV32ZICOND-NEXT: sltu a0, a0, a2 1155; RV32ZICOND-NEXT: xor a5, a3, a1 1156; RV32ZICOND-NEXT: sltu a1, a1, a3 1157; RV32ZICOND-NEXT: czero.eqz a1, a1, a5 1158; RV32ZICOND-NEXT: czero.nez a0, a0, a5 1159; RV32ZICOND-NEXT: or a0, a0, a1 1160; RV32ZICOND-NEXT: sw a2, 0(a4) 1161; RV32ZICOND-NEXT: sw a3, 4(a4) 1162; RV32ZICOND-NEXT: ret 1163; 1164; RV64ZICOND-LABEL: usubo.i64: 1165; RV64ZICOND: # %bb.0: # %entry 1166; RV64ZICOND-NEXT: sub a1, a0, a1 1167; RV64ZICOND-NEXT: sltu a0, a0, a1 1168; RV64ZICOND-NEXT: sd a1, 0(a2) 1169; RV64ZICOND-NEXT: ret 1170entry: 1171 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2) 1172 %val = extractvalue {i64, i1} %t, 0 1173 %obit = extractvalue {i64, i1} %t, 1 1174 store i64 %val, ptr %res 1175 ret i1 %obit 1176} 1177 1178define zeroext i1 @smulo.i32(i32 signext %v1, i32 signext %v2, ptr %res) { 1179; RV32-LABEL: smulo.i32: 1180; RV32: # %bb.0: # %entry 1181; RV32-NEXT: mulh a3, a0, a1 1182; RV32-NEXT: mul a1, a0, a1 1183; RV32-NEXT: srai a0, a1, 31 1184; RV32-NEXT: xor a0, a3, a0 1185; RV32-NEXT: snez a0, a0 1186; RV32-NEXT: sw a1, 0(a2) 1187; RV32-NEXT: ret 1188; 1189; RV64-LABEL: smulo.i32: 1190; RV64: # %bb.0: # %entry 1191; RV64-NEXT: mul a3, a0, a1 1192; RV64-NEXT: mulw a0, a0, a1 1193; RV64-NEXT: xor a0, a0, a3 1194; RV64-NEXT: snez a0, a0 1195; RV64-NEXT: sw a3, 0(a2) 1196; RV64-NEXT: ret 1197; 1198; RV32ZBA-LABEL: smulo.i32: 1199; RV32ZBA: # %bb.0: # %entry 1200; RV32ZBA-NEXT: mulh a3, a0, a1 1201; RV32ZBA-NEXT: mul a1, a0, a1 1202; RV32ZBA-NEXT: srai a0, a1, 31 1203; RV32ZBA-NEXT: xor a0, a3, a0 1204; RV32ZBA-NEXT: snez a0, a0 1205; RV32ZBA-NEXT: sw a1, 0(a2) 1206; RV32ZBA-NEXT: ret 1207; 1208; RV64ZBA-LABEL: smulo.i32: 1209; RV64ZBA: # %bb.0: # %entry 1210; RV64ZBA-NEXT: mul a3, a0, a1 1211; RV64ZBA-NEXT: mulw a0, a0, a1 1212; RV64ZBA-NEXT: xor a0, a0, a3 1213; RV64ZBA-NEXT: snez a0, a0 1214; RV64ZBA-NEXT: sw a3, 0(a2) 1215; RV64ZBA-NEXT: ret 1216; 1217; RV32ZICOND-LABEL: smulo.i32: 1218; RV32ZICOND: # %bb.0: # %entry 1219; RV32ZICOND-NEXT: mulh a3, a0, a1 1220; RV32ZICOND-NEXT: mul a1, a0, a1 1221; RV32ZICOND-NEXT: srai a0, a1, 31 1222; RV32ZICOND-NEXT: xor a0, a3, a0 1223; RV32ZICOND-NEXT: snez a0, a0 1224; RV32ZICOND-NEXT: sw a1, 0(a2) 1225; RV32ZICOND-NEXT: ret 1226; 1227; RV64ZICOND-LABEL: smulo.i32: 1228; RV64ZICOND: # %bb.0: # %entry 1229; RV64ZICOND-NEXT: mul a3, a0, a1 1230; RV64ZICOND-NEXT: mulw a0, a0, a1 1231; RV64ZICOND-NEXT: xor a0, a0, a3 1232; RV64ZICOND-NEXT: snez a0, a0 1233; RV64ZICOND-NEXT: sw a3, 0(a2) 1234; RV64ZICOND-NEXT: ret 1235entry: 1236 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2) 1237 %val = extractvalue {i32, i1} %t, 0 1238 %obit = extractvalue {i32, i1} %t, 1 1239 store i32 %val, ptr %res 1240 ret i1 %obit 1241} 1242 1243define zeroext i1 @smulo2.i32(i32 signext %v1, ptr %res) { 1244; RV32-LABEL: smulo2.i32: 1245; RV32: # %bb.0: # %entry 1246; RV32-NEXT: li a2, 13 1247; RV32-NEXT: mulh a3, a0, a2 1248; RV32-NEXT: mul a2, a0, a2 1249; RV32-NEXT: srai a0, a2, 31 1250; RV32-NEXT: xor a0, a3, a0 1251; RV32-NEXT: snez a0, a0 1252; RV32-NEXT: sw a2, 0(a1) 1253; RV32-NEXT: ret 1254; 1255; RV64-LABEL: smulo2.i32: 1256; RV64: # %bb.0: # %entry 1257; RV64-NEXT: li a2, 13 1258; RV64-NEXT: mul a3, a0, a2 1259; RV64-NEXT: mulw a0, a0, a2 1260; RV64-NEXT: xor a0, a0, a3 1261; RV64-NEXT: snez a0, a0 1262; RV64-NEXT: sw a3, 0(a1) 1263; RV64-NEXT: ret 1264; 1265; RV32ZBA-LABEL: smulo2.i32: 1266; RV32ZBA: # %bb.0: # %entry 1267; RV32ZBA-NEXT: li a2, 13 1268; RV32ZBA-NEXT: sh1add a3, a0, a0 1269; RV32ZBA-NEXT: mulh a2, a0, a2 1270; RV32ZBA-NEXT: sh2add a3, a3, a0 1271; RV32ZBA-NEXT: srai a0, a3, 31 1272; RV32ZBA-NEXT: xor a0, a2, a0 1273; RV32ZBA-NEXT: snez a0, a0 1274; RV32ZBA-NEXT: sw a3, 0(a1) 1275; RV32ZBA-NEXT: ret 1276; 1277; RV64ZBA-LABEL: smulo2.i32: 1278; RV64ZBA: # %bb.0: # %entry 1279; RV64ZBA-NEXT: sh1add a2, a0, a0 1280; RV64ZBA-NEXT: sh2add a2, a2, a0 1281; RV64ZBA-NEXT: sext.w a0, a2 1282; RV64ZBA-NEXT: xor a0, a0, a2 1283; RV64ZBA-NEXT: snez a0, a0 1284; RV64ZBA-NEXT: sw a2, 0(a1) 1285; RV64ZBA-NEXT: ret 1286; 1287; RV32ZICOND-LABEL: smulo2.i32: 1288; RV32ZICOND: # %bb.0: # %entry 1289; RV32ZICOND-NEXT: li a2, 13 1290; RV32ZICOND-NEXT: mulh a3, a0, a2 1291; RV32ZICOND-NEXT: mul a2, a0, a2 1292; RV32ZICOND-NEXT: srai a0, a2, 31 1293; RV32ZICOND-NEXT: xor a0, a3, a0 1294; RV32ZICOND-NEXT: snez a0, a0 1295; RV32ZICOND-NEXT: sw a2, 0(a1) 1296; RV32ZICOND-NEXT: ret 1297; 1298; RV64ZICOND-LABEL: smulo2.i32: 1299; RV64ZICOND: # %bb.0: # %entry 1300; RV64ZICOND-NEXT: li a2, 13 1301; RV64ZICOND-NEXT: mul a3, a0, a2 1302; RV64ZICOND-NEXT: mulw a0, a0, a2 1303; RV64ZICOND-NEXT: xor a0, a0, a3 1304; RV64ZICOND-NEXT: snez a0, a0 1305; RV64ZICOND-NEXT: sw a3, 0(a1) 1306; RV64ZICOND-NEXT: ret 1307entry: 1308 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 13) 1309 %val = extractvalue {i32, i1} %t, 0 1310 %obit = extractvalue {i32, i1} %t, 1 1311 store i32 %val, ptr %res 1312 ret i1 %obit 1313} 1314 1315define zeroext i1 @smulo.i64(i64 %v1, i64 %v2, ptr %res) { 1316; RV32-LABEL: smulo.i64: 1317; RV32: # %bb.0: # %entry 1318; RV32-NEXT: mulhu a5, a0, a2 1319; RV32-NEXT: mul a6, a1, a2 1320; RV32-NEXT: mulhsu a7, a1, a2 1321; RV32-NEXT: mul t0, a3, a0 1322; RV32-NEXT: mulh t1, a1, a3 1323; RV32-NEXT: mul a1, a1, a3 1324; RV32-NEXT: mulhsu a3, a3, a0 1325; RV32-NEXT: mul a2, a0, a2 1326; RV32-NEXT: add a5, a6, a5 1327; RV32-NEXT: sltu a0, a5, a6 1328; RV32-NEXT: add a5, t0, a5 1329; RV32-NEXT: add a0, a7, a0 1330; RV32-NEXT: sltu a6, a5, t0 1331; RV32-NEXT: srai a7, a5, 31 1332; RV32-NEXT: add a3, a3, a6 1333; RV32-NEXT: srai a6, a0, 31 1334; RV32-NEXT: add t0, a0, a3 1335; RV32-NEXT: srai a3, a3, 31 1336; RV32-NEXT: sltu a0, t0, a0 1337; RV32-NEXT: add a3, a6, a3 1338; RV32-NEXT: add t0, a1, t0 1339; RV32-NEXT: add a0, a3, a0 1340; RV32-NEXT: sltu a1, t0, a1 1341; RV32-NEXT: xor a3, t0, a7 1342; RV32-NEXT: add a0, t1, a0 1343; RV32-NEXT: add a0, a0, a1 1344; RV32-NEXT: xor a0, a0, a7 1345; RV32-NEXT: or a0, a3, a0 1346; RV32-NEXT: snez a0, a0 1347; RV32-NEXT: sw a2, 0(a4) 1348; RV32-NEXT: sw a5, 4(a4) 1349; RV32-NEXT: ret 1350; 1351; RV64-LABEL: smulo.i64: 1352; RV64: # %bb.0: # %entry 1353; RV64-NEXT: mulh a3, a0, a1 1354; RV64-NEXT: mul a1, a0, a1 1355; RV64-NEXT: srai a0, a1, 63 1356; RV64-NEXT: xor a0, a3, a0 1357; RV64-NEXT: snez a0, a0 1358; RV64-NEXT: sd a1, 0(a2) 1359; RV64-NEXT: ret 1360; 1361; RV32ZBA-LABEL: smulo.i64: 1362; RV32ZBA: # %bb.0: # %entry 1363; RV32ZBA-NEXT: mulhu a5, a0, a2 1364; RV32ZBA-NEXT: mul a6, a1, a2 1365; RV32ZBA-NEXT: mulhsu a7, a1, a2 1366; RV32ZBA-NEXT: mul t0, a3, a0 1367; RV32ZBA-NEXT: mulh t1, a1, a3 1368; RV32ZBA-NEXT: mul a1, a1, a3 1369; RV32ZBA-NEXT: mulhsu a3, a3, a0 1370; RV32ZBA-NEXT: mul a2, a0, a2 1371; RV32ZBA-NEXT: add a5, a6, a5 1372; RV32ZBA-NEXT: sltu a0, a5, a6 1373; RV32ZBA-NEXT: add a5, t0, a5 1374; RV32ZBA-NEXT: add a0, a7, a0 1375; RV32ZBA-NEXT: sltu a6, a5, t0 1376; RV32ZBA-NEXT: srai a7, a5, 31 1377; RV32ZBA-NEXT: add a3, a3, a6 1378; RV32ZBA-NEXT: srai a6, a0, 31 1379; RV32ZBA-NEXT: add t0, a0, a3 1380; RV32ZBA-NEXT: srai a3, a3, 31 1381; RV32ZBA-NEXT: sltu a0, t0, a0 1382; RV32ZBA-NEXT: add a3, a6, a3 1383; RV32ZBA-NEXT: add t0, a1, t0 1384; RV32ZBA-NEXT: add a0, a3, a0 1385; RV32ZBA-NEXT: sltu a1, t0, a1 1386; RV32ZBA-NEXT: xor a3, t0, a7 1387; RV32ZBA-NEXT: add a0, t1, a0 1388; RV32ZBA-NEXT: add a0, a0, a1 1389; RV32ZBA-NEXT: xor a0, a0, a7 1390; RV32ZBA-NEXT: or a0, a3, a0 1391; RV32ZBA-NEXT: snez a0, a0 1392; RV32ZBA-NEXT: sw a2, 0(a4) 1393; RV32ZBA-NEXT: sw a5, 4(a4) 1394; RV32ZBA-NEXT: ret 1395; 1396; RV64ZBA-LABEL: smulo.i64: 1397; RV64ZBA: # %bb.0: # %entry 1398; RV64ZBA-NEXT: mulh a3, a0, a1 1399; RV64ZBA-NEXT: mul a1, a0, a1 1400; RV64ZBA-NEXT: srai a0, a1, 63 1401; RV64ZBA-NEXT: xor a0, a3, a0 1402; RV64ZBA-NEXT: snez a0, a0 1403; RV64ZBA-NEXT: sd a1, 0(a2) 1404; RV64ZBA-NEXT: ret 1405; 1406; RV32ZICOND-LABEL: smulo.i64: 1407; RV32ZICOND: # %bb.0: # %entry 1408; RV32ZICOND-NEXT: mulhu a5, a0, a2 1409; RV32ZICOND-NEXT: mul a6, a1, a2 1410; RV32ZICOND-NEXT: mulhsu a7, a1, a2 1411; RV32ZICOND-NEXT: mul t0, a3, a0 1412; RV32ZICOND-NEXT: mulh t1, a1, a3 1413; RV32ZICOND-NEXT: mul a1, a1, a3 1414; RV32ZICOND-NEXT: mulhsu a3, a3, a0 1415; RV32ZICOND-NEXT: mul a2, a0, a2 1416; RV32ZICOND-NEXT: add a5, a6, a5 1417; RV32ZICOND-NEXT: sltu a0, a5, a6 1418; RV32ZICOND-NEXT: add a5, t0, a5 1419; RV32ZICOND-NEXT: add a0, a7, a0 1420; RV32ZICOND-NEXT: sltu a6, a5, t0 1421; RV32ZICOND-NEXT: srai a7, a5, 31 1422; RV32ZICOND-NEXT: add a3, a3, a6 1423; RV32ZICOND-NEXT: srai a6, a0, 31 1424; RV32ZICOND-NEXT: add t0, a0, a3 1425; RV32ZICOND-NEXT: srai a3, a3, 31 1426; RV32ZICOND-NEXT: sltu a0, t0, a0 1427; RV32ZICOND-NEXT: add a3, a6, a3 1428; RV32ZICOND-NEXT: add t0, a1, t0 1429; RV32ZICOND-NEXT: add a0, a3, a0 1430; RV32ZICOND-NEXT: sltu a1, t0, a1 1431; RV32ZICOND-NEXT: xor a3, t0, a7 1432; RV32ZICOND-NEXT: add a0, t1, a0 1433; RV32ZICOND-NEXT: add a0, a0, a1 1434; RV32ZICOND-NEXT: xor a0, a0, a7 1435; RV32ZICOND-NEXT: or a0, a3, a0 1436; RV32ZICOND-NEXT: snez a0, a0 1437; RV32ZICOND-NEXT: sw a2, 0(a4) 1438; RV32ZICOND-NEXT: sw a5, 4(a4) 1439; RV32ZICOND-NEXT: ret 1440; 1441; RV64ZICOND-LABEL: smulo.i64: 1442; RV64ZICOND: # %bb.0: # %entry 1443; RV64ZICOND-NEXT: mulh a3, a0, a1 1444; RV64ZICOND-NEXT: mul a1, a0, a1 1445; RV64ZICOND-NEXT: srai a0, a1, 63 1446; RV64ZICOND-NEXT: xor a0, a3, a0 1447; RV64ZICOND-NEXT: snez a0, a0 1448; RV64ZICOND-NEXT: sd a1, 0(a2) 1449; RV64ZICOND-NEXT: ret 1450entry: 1451 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2) 1452 %val = extractvalue {i64, i1} %t, 0 1453 %obit = extractvalue {i64, i1} %t, 1 1454 store i64 %val, ptr %res 1455 ret i1 %obit 1456} 1457 1458define zeroext i1 @smulo2.i64(i64 %v1, ptr %res) { 1459; RV32-LABEL: smulo2.i64: 1460; RV32: # %bb.0: # %entry 1461; RV32-NEXT: li a3, 13 1462; RV32-NEXT: mulhu a4, a0, a3 1463; RV32-NEXT: mul a5, a1, a3 1464; RV32-NEXT: mulh a1, a1, a3 1465; RV32-NEXT: mul a3, a0, a3 1466; RV32-NEXT: add a4, a5, a4 1467; RV32-NEXT: sltu a0, a4, a5 1468; RV32-NEXT: srai a5, a4, 31 1469; RV32-NEXT: add a0, a1, a0 1470; RV32-NEXT: xor a1, a0, a5 1471; RV32-NEXT: srai a0, a0, 31 1472; RV32-NEXT: xor a0, a0, a5 1473; RV32-NEXT: or a0, a1, a0 1474; RV32-NEXT: snez a0, a0 1475; RV32-NEXT: sw a3, 0(a2) 1476; RV32-NEXT: sw a4, 4(a2) 1477; RV32-NEXT: ret 1478; 1479; RV64-LABEL: smulo2.i64: 1480; RV64: # %bb.0: # %entry 1481; RV64-NEXT: li a2, 13 1482; RV64-NEXT: mulh a3, a0, a2 1483; RV64-NEXT: mul a2, a0, a2 1484; RV64-NEXT: srai a0, a2, 63 1485; RV64-NEXT: xor a0, a3, a0 1486; RV64-NEXT: snez a0, a0 1487; RV64-NEXT: sd a2, 0(a1) 1488; RV64-NEXT: ret 1489; 1490; RV32ZBA-LABEL: smulo2.i64: 1491; RV32ZBA: # %bb.0: # %entry 1492; RV32ZBA-NEXT: li a3, 13 1493; RV32ZBA-NEXT: sh1add a4, a1, a1 1494; RV32ZBA-NEXT: sh1add a5, a0, a0 1495; RV32ZBA-NEXT: sh2add a4, a4, a1 1496; RV32ZBA-NEXT: mulh a1, a1, a3 1497; RV32ZBA-NEXT: mulhu a3, a0, a3 1498; RV32ZBA-NEXT: sh2add a5, a5, a0 1499; RV32ZBA-NEXT: add a3, a4, a3 1500; RV32ZBA-NEXT: sltu a0, a3, a4 1501; RV32ZBA-NEXT: srai a4, a3, 31 1502; RV32ZBA-NEXT: add a0, a1, a0 1503; RV32ZBA-NEXT: xor a1, a0, a4 1504; RV32ZBA-NEXT: srai a0, a0, 31 1505; RV32ZBA-NEXT: xor a0, a0, a4 1506; RV32ZBA-NEXT: or a0, a1, a0 1507; RV32ZBA-NEXT: snez a0, a0 1508; RV32ZBA-NEXT: sw a5, 0(a2) 1509; RV32ZBA-NEXT: sw a3, 4(a2) 1510; RV32ZBA-NEXT: ret 1511; 1512; RV64ZBA-LABEL: smulo2.i64: 1513; RV64ZBA: # %bb.0: # %entry 1514; RV64ZBA-NEXT: li a2, 13 1515; RV64ZBA-NEXT: sh1add a3, a0, a0 1516; RV64ZBA-NEXT: mulh a2, a0, a2 1517; RV64ZBA-NEXT: sh2add a3, a3, a0 1518; RV64ZBA-NEXT: srai a0, a3, 63 1519; RV64ZBA-NEXT: xor a0, a2, a0 1520; RV64ZBA-NEXT: snez a0, a0 1521; RV64ZBA-NEXT: sd a3, 0(a1) 1522; RV64ZBA-NEXT: ret 1523; 1524; RV32ZICOND-LABEL: smulo2.i64: 1525; RV32ZICOND: # %bb.0: # %entry 1526; RV32ZICOND-NEXT: li a3, 13 1527; RV32ZICOND-NEXT: mulhu a4, a0, a3 1528; RV32ZICOND-NEXT: mul a5, a1, a3 1529; RV32ZICOND-NEXT: mulh a1, a1, a3 1530; RV32ZICOND-NEXT: mul a3, a0, a3 1531; RV32ZICOND-NEXT: add a4, a5, a4 1532; RV32ZICOND-NEXT: sltu a0, a4, a5 1533; RV32ZICOND-NEXT: srai a5, a4, 31 1534; RV32ZICOND-NEXT: add a0, a1, a0 1535; RV32ZICOND-NEXT: xor a1, a0, a5 1536; RV32ZICOND-NEXT: srai a0, a0, 31 1537; RV32ZICOND-NEXT: xor a0, a0, a5 1538; RV32ZICOND-NEXT: or a0, a1, a0 1539; RV32ZICOND-NEXT: snez a0, a0 1540; RV32ZICOND-NEXT: sw a3, 0(a2) 1541; RV32ZICOND-NEXT: sw a4, 4(a2) 1542; RV32ZICOND-NEXT: ret 1543; 1544; RV64ZICOND-LABEL: smulo2.i64: 1545; RV64ZICOND: # %bb.0: # %entry 1546; RV64ZICOND-NEXT: li a2, 13 1547; RV64ZICOND-NEXT: mulh a3, a0, a2 1548; RV64ZICOND-NEXT: mul a2, a0, a2 1549; RV64ZICOND-NEXT: srai a0, a2, 63 1550; RV64ZICOND-NEXT: xor a0, a3, a0 1551; RV64ZICOND-NEXT: snez a0, a0 1552; RV64ZICOND-NEXT: sd a2, 0(a1) 1553; RV64ZICOND-NEXT: ret 1554entry: 1555 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 13) 1556 %val = extractvalue {i64, i1} %t, 0 1557 %obit = extractvalue {i64, i1} %t, 1 1558 store i64 %val, ptr %res 1559 ret i1 %obit 1560} 1561 1562define zeroext i1 @umulo.i32(i32 signext %v1, i32 signext %v2, ptr %res) { 1563; RV32-LABEL: umulo.i32: 1564; RV32: # %bb.0: # %entry 1565; RV32-NEXT: mulhu a3, a0, a1 1566; RV32-NEXT: snez a3, a3 1567; RV32-NEXT: mul a0, a0, a1 1568; RV32-NEXT: sw a0, 0(a2) 1569; RV32-NEXT: mv a0, a3 1570; RV32-NEXT: ret 1571; 1572; RV64-LABEL: umulo.i32: 1573; RV64: # %bb.0: # %entry 1574; RV64-NEXT: slli a1, a1, 32 1575; RV64-NEXT: slli a0, a0, 32 1576; RV64-NEXT: mulhu a1, a0, a1 1577; RV64-NEXT: srli a0, a1, 32 1578; RV64-NEXT: snez a0, a0 1579; RV64-NEXT: sw a1, 0(a2) 1580; RV64-NEXT: ret 1581; 1582; RV32ZBA-LABEL: umulo.i32: 1583; RV32ZBA: # %bb.0: # %entry 1584; RV32ZBA-NEXT: mulhu a3, a0, a1 1585; RV32ZBA-NEXT: snez a3, a3 1586; RV32ZBA-NEXT: mul a0, a0, a1 1587; RV32ZBA-NEXT: sw a0, 0(a2) 1588; RV32ZBA-NEXT: mv a0, a3 1589; RV32ZBA-NEXT: ret 1590; 1591; RV64ZBA-LABEL: umulo.i32: 1592; RV64ZBA: # %bb.0: # %entry 1593; RV64ZBA-NEXT: zext.w a1, a1 1594; RV64ZBA-NEXT: zext.w a0, a0 1595; RV64ZBA-NEXT: mul a1, a0, a1 1596; RV64ZBA-NEXT: srli a0, a1, 32 1597; RV64ZBA-NEXT: snez a0, a0 1598; RV64ZBA-NEXT: sw a1, 0(a2) 1599; RV64ZBA-NEXT: ret 1600; 1601; RV32ZICOND-LABEL: umulo.i32: 1602; RV32ZICOND: # %bb.0: # %entry 1603; RV32ZICOND-NEXT: mulhu a3, a0, a1 1604; RV32ZICOND-NEXT: snez a3, a3 1605; RV32ZICOND-NEXT: mul a0, a0, a1 1606; RV32ZICOND-NEXT: sw a0, 0(a2) 1607; RV32ZICOND-NEXT: mv a0, a3 1608; RV32ZICOND-NEXT: ret 1609; 1610; RV64ZICOND-LABEL: umulo.i32: 1611; RV64ZICOND: # %bb.0: # %entry 1612; RV64ZICOND-NEXT: slli a1, a1, 32 1613; RV64ZICOND-NEXT: slli a0, a0, 32 1614; RV64ZICOND-NEXT: mulhu a1, a0, a1 1615; RV64ZICOND-NEXT: srli a0, a1, 32 1616; RV64ZICOND-NEXT: snez a0, a0 1617; RV64ZICOND-NEXT: sw a1, 0(a2) 1618; RV64ZICOND-NEXT: ret 1619entry: 1620 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2) 1621 %val = extractvalue {i32, i1} %t, 0 1622 %obit = extractvalue {i32, i1} %t, 1 1623 store i32 %val, ptr %res 1624 ret i1 %obit 1625} 1626 1627define zeroext i1 @umulo2.i32(i32 signext %v1, ptr %res) { 1628; RV32-LABEL: umulo2.i32: 1629; RV32: # %bb.0: # %entry 1630; RV32-NEXT: li a3, 13 1631; RV32-NEXT: mulhu a2, a0, a3 1632; RV32-NEXT: snez a2, a2 1633; RV32-NEXT: mul a0, a0, a3 1634; RV32-NEXT: sw a0, 0(a1) 1635; RV32-NEXT: mv a0, a2 1636; RV32-NEXT: ret 1637; 1638; RV64-LABEL: umulo2.i32: 1639; RV64: # %bb.0: # %entry 1640; RV64-NEXT: li a2, 13 1641; RV64-NEXT: slli a2, a2, 32 1642; RV64-NEXT: slli a0, a0, 32 1643; RV64-NEXT: mulhu a2, a0, a2 1644; RV64-NEXT: srli a0, a2, 32 1645; RV64-NEXT: snez a0, a0 1646; RV64-NEXT: sw a2, 0(a1) 1647; RV64-NEXT: ret 1648; 1649; RV32ZBA-LABEL: umulo2.i32: 1650; RV32ZBA: # %bb.0: # %entry 1651; RV32ZBA-NEXT: li a2, 13 1652; RV32ZBA-NEXT: sh1add a3, a0, a0 1653; RV32ZBA-NEXT: mulhu a2, a0, a2 1654; RV32ZBA-NEXT: snez a2, a2 1655; RV32ZBA-NEXT: sh2add a0, a3, a0 1656; RV32ZBA-NEXT: sw a0, 0(a1) 1657; RV32ZBA-NEXT: mv a0, a2 1658; RV32ZBA-NEXT: ret 1659; 1660; RV64ZBA-LABEL: umulo2.i32: 1661; RV64ZBA: # %bb.0: # %entry 1662; RV64ZBA-NEXT: zext.w a2, a0 1663; RV64ZBA-NEXT: sh1add.uw a0, a0, a2 1664; RV64ZBA-NEXT: sh2add a2, a0, a2 1665; RV64ZBA-NEXT: srli a0, a2, 32 1666; RV64ZBA-NEXT: snez a0, a0 1667; RV64ZBA-NEXT: sw a2, 0(a1) 1668; RV64ZBA-NEXT: ret 1669; 1670; RV32ZICOND-LABEL: umulo2.i32: 1671; RV32ZICOND: # %bb.0: # %entry 1672; RV32ZICOND-NEXT: li a3, 13 1673; RV32ZICOND-NEXT: mulhu a2, a0, a3 1674; RV32ZICOND-NEXT: snez a2, a2 1675; RV32ZICOND-NEXT: mul a0, a0, a3 1676; RV32ZICOND-NEXT: sw a0, 0(a1) 1677; RV32ZICOND-NEXT: mv a0, a2 1678; RV32ZICOND-NEXT: ret 1679; 1680; RV64ZICOND-LABEL: umulo2.i32: 1681; RV64ZICOND: # %bb.0: # %entry 1682; RV64ZICOND-NEXT: li a2, 13 1683; RV64ZICOND-NEXT: slli a2, a2, 32 1684; RV64ZICOND-NEXT: slli a0, a0, 32 1685; RV64ZICOND-NEXT: mulhu a2, a0, a2 1686; RV64ZICOND-NEXT: srli a0, a2, 32 1687; RV64ZICOND-NEXT: snez a0, a0 1688; RV64ZICOND-NEXT: sw a2, 0(a1) 1689; RV64ZICOND-NEXT: ret 1690entry: 1691 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 13) 1692 %val = extractvalue {i32, i1} %t, 0 1693 %obit = extractvalue {i32, i1} %t, 1 1694 store i32 %val, ptr %res 1695 ret i1 %obit 1696} 1697 1698; Similar to umulo.i32, but storing the overflow and returning the result. 1699define signext i32 @umulo3.i32(i32 signext %0, i32 signext %1, ptr %2) { 1700; RV32-LABEL: umulo3.i32: 1701; RV32: # %bb.0: 1702; RV32-NEXT: mul a3, a0, a1 1703; RV32-NEXT: mulhu a0, a0, a1 1704; RV32-NEXT: snez a0, a0 1705; RV32-NEXT: sw a0, 0(a2) 1706; RV32-NEXT: mv a0, a3 1707; RV32-NEXT: ret 1708; 1709; RV64-LABEL: umulo3.i32: 1710; RV64: # %bb.0: 1711; RV64-NEXT: slli a1, a1, 32 1712; RV64-NEXT: slli a0, a0, 32 1713; RV64-NEXT: mulhu a0, a0, a1 1714; RV64-NEXT: srli a1, a0, 32 1715; RV64-NEXT: snez a1, a1 1716; RV64-NEXT: sext.w a0, a0 1717; RV64-NEXT: sw a1, 0(a2) 1718; RV64-NEXT: ret 1719; 1720; RV32ZBA-LABEL: umulo3.i32: 1721; RV32ZBA: # %bb.0: 1722; RV32ZBA-NEXT: mul a3, a0, a1 1723; RV32ZBA-NEXT: mulhu a0, a0, a1 1724; RV32ZBA-NEXT: snez a0, a0 1725; RV32ZBA-NEXT: sw a0, 0(a2) 1726; RV32ZBA-NEXT: mv a0, a3 1727; RV32ZBA-NEXT: ret 1728; 1729; RV64ZBA-LABEL: umulo3.i32: 1730; RV64ZBA: # %bb.0: 1731; RV64ZBA-NEXT: zext.w a1, a1 1732; RV64ZBA-NEXT: zext.w a0, a0 1733; RV64ZBA-NEXT: mul a3, a0, a1 1734; RV64ZBA-NEXT: srli a3, a3, 32 1735; RV64ZBA-NEXT: snez a3, a3 1736; RV64ZBA-NEXT: mulw a0, a0, a1 1737; RV64ZBA-NEXT: sw a3, 0(a2) 1738; RV64ZBA-NEXT: ret 1739; 1740; RV32ZICOND-LABEL: umulo3.i32: 1741; RV32ZICOND: # %bb.0: 1742; RV32ZICOND-NEXT: mul a3, a0, a1 1743; RV32ZICOND-NEXT: mulhu a0, a0, a1 1744; RV32ZICOND-NEXT: snez a0, a0 1745; RV32ZICOND-NEXT: sw a0, 0(a2) 1746; RV32ZICOND-NEXT: mv a0, a3 1747; RV32ZICOND-NEXT: ret 1748; 1749; RV64ZICOND-LABEL: umulo3.i32: 1750; RV64ZICOND: # %bb.0: 1751; RV64ZICOND-NEXT: slli a1, a1, 32 1752; RV64ZICOND-NEXT: slli a0, a0, 32 1753; RV64ZICOND-NEXT: mulhu a0, a0, a1 1754; RV64ZICOND-NEXT: srli a1, a0, 32 1755; RV64ZICOND-NEXT: snez a1, a1 1756; RV64ZICOND-NEXT: sext.w a0, a0 1757; RV64ZICOND-NEXT: sw a1, 0(a2) 1758; RV64ZICOND-NEXT: ret 1759 %4 = tail call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %0, i32 %1) 1760 %5 = extractvalue { i32, i1 } %4, 1 1761 %6 = extractvalue { i32, i1 } %4, 0 1762 %7 = zext i1 %5 to i32 1763 store i32 %7, ptr %2, align 4 1764 ret i32 %6 1765} 1766 1767define zeroext i1 @umulo.i64(i64 %v1, i64 %v2, ptr %res) { 1768; RV32-LABEL: umulo.i64: 1769; RV32: # %bb.0: # %entry 1770; RV32-NEXT: mul a5, a3, a0 1771; RV32-NEXT: mul a6, a1, a2 1772; RV32-NEXT: mulhu a7, a0, a2 1773; RV32-NEXT: snez t0, a3 1774; RV32-NEXT: mulhu a3, a3, a0 1775; RV32-NEXT: mul t1, a0, a2 1776; RV32-NEXT: mulhu a0, a1, a2 1777; RV32-NEXT: snez a1, a1 1778; RV32-NEXT: add a5, a6, a5 1779; RV32-NEXT: and a1, a1, t0 1780; RV32-NEXT: snez a0, a0 1781; RV32-NEXT: snez a2, a3 1782; RV32-NEXT: add a5, a7, a5 1783; RV32-NEXT: or a0, a1, a0 1784; RV32-NEXT: sltu a1, a5, a7 1785; RV32-NEXT: or a0, a0, a2 1786; RV32-NEXT: or a0, a0, a1 1787; RV32-NEXT: sw t1, 0(a4) 1788; RV32-NEXT: sw a5, 4(a4) 1789; RV32-NEXT: ret 1790; 1791; RV64-LABEL: umulo.i64: 1792; RV64: # %bb.0: # %entry 1793; RV64-NEXT: mulhu a3, a0, a1 1794; RV64-NEXT: snez a3, a3 1795; RV64-NEXT: mul a0, a0, a1 1796; RV64-NEXT: sd a0, 0(a2) 1797; RV64-NEXT: mv a0, a3 1798; RV64-NEXT: ret 1799; 1800; RV32ZBA-LABEL: umulo.i64: 1801; RV32ZBA: # %bb.0: # %entry 1802; RV32ZBA-NEXT: mul a5, a3, a0 1803; RV32ZBA-NEXT: mul a6, a1, a2 1804; RV32ZBA-NEXT: mulhu a7, a0, a2 1805; RV32ZBA-NEXT: snez t0, a3 1806; RV32ZBA-NEXT: mulhu a3, a3, a0 1807; RV32ZBA-NEXT: mul t1, a0, a2 1808; RV32ZBA-NEXT: mulhu a0, a1, a2 1809; RV32ZBA-NEXT: snez a1, a1 1810; RV32ZBA-NEXT: add a5, a6, a5 1811; RV32ZBA-NEXT: and a1, a1, t0 1812; RV32ZBA-NEXT: snez a0, a0 1813; RV32ZBA-NEXT: snez a2, a3 1814; RV32ZBA-NEXT: add a5, a7, a5 1815; RV32ZBA-NEXT: or a0, a1, a0 1816; RV32ZBA-NEXT: sltu a1, a5, a7 1817; RV32ZBA-NEXT: or a0, a0, a2 1818; RV32ZBA-NEXT: or a0, a0, a1 1819; RV32ZBA-NEXT: sw t1, 0(a4) 1820; RV32ZBA-NEXT: sw a5, 4(a4) 1821; RV32ZBA-NEXT: ret 1822; 1823; RV64ZBA-LABEL: umulo.i64: 1824; RV64ZBA: # %bb.0: # %entry 1825; RV64ZBA-NEXT: mulhu a3, a0, a1 1826; RV64ZBA-NEXT: snez a3, a3 1827; RV64ZBA-NEXT: mul a0, a0, a1 1828; RV64ZBA-NEXT: sd a0, 0(a2) 1829; RV64ZBA-NEXT: mv a0, a3 1830; RV64ZBA-NEXT: ret 1831; 1832; RV32ZICOND-LABEL: umulo.i64: 1833; RV32ZICOND: # %bb.0: # %entry 1834; RV32ZICOND-NEXT: mul a5, a3, a0 1835; RV32ZICOND-NEXT: mul a6, a1, a2 1836; RV32ZICOND-NEXT: mulhu a7, a0, a2 1837; RV32ZICOND-NEXT: snez t0, a3 1838; RV32ZICOND-NEXT: mulhu a3, a3, a0 1839; RV32ZICOND-NEXT: mul t1, a0, a2 1840; RV32ZICOND-NEXT: mulhu a0, a1, a2 1841; RV32ZICOND-NEXT: snez a1, a1 1842; RV32ZICOND-NEXT: add a5, a6, a5 1843; RV32ZICOND-NEXT: and a1, a1, t0 1844; RV32ZICOND-NEXT: snez a0, a0 1845; RV32ZICOND-NEXT: snez a2, a3 1846; RV32ZICOND-NEXT: add a5, a7, a5 1847; RV32ZICOND-NEXT: or a0, a1, a0 1848; RV32ZICOND-NEXT: sltu a1, a5, a7 1849; RV32ZICOND-NEXT: or a0, a0, a2 1850; RV32ZICOND-NEXT: or a0, a0, a1 1851; RV32ZICOND-NEXT: sw t1, 0(a4) 1852; RV32ZICOND-NEXT: sw a5, 4(a4) 1853; RV32ZICOND-NEXT: ret 1854; 1855; RV64ZICOND-LABEL: umulo.i64: 1856; RV64ZICOND: # %bb.0: # %entry 1857; RV64ZICOND-NEXT: mulhu a3, a0, a1 1858; RV64ZICOND-NEXT: snez a3, a3 1859; RV64ZICOND-NEXT: mul a0, a0, a1 1860; RV64ZICOND-NEXT: sd a0, 0(a2) 1861; RV64ZICOND-NEXT: mv a0, a3 1862; RV64ZICOND-NEXT: ret 1863entry: 1864 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2) 1865 %val = extractvalue {i64, i1} %t, 0 1866 %obit = extractvalue {i64, i1} %t, 1 1867 store i64 %val, ptr %res 1868 ret i1 %obit 1869} 1870 1871define zeroext i1 @umulo2.i64(i64 %v1, ptr %res) { 1872; RV32-LABEL: umulo2.i64: 1873; RV32: # %bb.0: # %entry 1874; RV32-NEXT: li a3, 13 1875; RV32-NEXT: mul a4, a1, a3 1876; RV32-NEXT: mulhu a5, a0, a3 1877; RV32-NEXT: mulhu a1, a1, a3 1878; RV32-NEXT: mul a3, a0, a3 1879; RV32-NEXT: add a4, a5, a4 1880; RV32-NEXT: snez a0, a1 1881; RV32-NEXT: sltu a1, a4, a5 1882; RV32-NEXT: or a0, a0, a1 1883; RV32-NEXT: sw a3, 0(a2) 1884; RV32-NEXT: sw a4, 4(a2) 1885; RV32-NEXT: ret 1886; 1887; RV64-LABEL: umulo2.i64: 1888; RV64: # %bb.0: # %entry 1889; RV64-NEXT: li a3, 13 1890; RV64-NEXT: mulhu a2, a0, a3 1891; RV64-NEXT: snez a2, a2 1892; RV64-NEXT: mul a0, a0, a3 1893; RV64-NEXT: sd a0, 0(a1) 1894; RV64-NEXT: mv a0, a2 1895; RV64-NEXT: ret 1896; 1897; RV32ZBA-LABEL: umulo2.i64: 1898; RV32ZBA: # %bb.0: # %entry 1899; RV32ZBA-NEXT: li a3, 13 1900; RV32ZBA-NEXT: sh1add a4, a1, a1 1901; RV32ZBA-NEXT: sh1add a5, a0, a0 1902; RV32ZBA-NEXT: sh2add a4, a4, a1 1903; RV32ZBA-NEXT: mulhu a1, a1, a3 1904; RV32ZBA-NEXT: mulhu a3, a0, a3 1905; RV32ZBA-NEXT: sh2add a5, a5, a0 1906; RV32ZBA-NEXT: add a4, a3, a4 1907; RV32ZBA-NEXT: snez a0, a1 1908; RV32ZBA-NEXT: sltu a1, a4, a3 1909; RV32ZBA-NEXT: or a0, a0, a1 1910; RV32ZBA-NEXT: sw a5, 0(a2) 1911; RV32ZBA-NEXT: sw a4, 4(a2) 1912; RV32ZBA-NEXT: ret 1913; 1914; RV64ZBA-LABEL: umulo2.i64: 1915; RV64ZBA: # %bb.0: # %entry 1916; RV64ZBA-NEXT: li a2, 13 1917; RV64ZBA-NEXT: sh1add a3, a0, a0 1918; RV64ZBA-NEXT: mulhu a2, a0, a2 1919; RV64ZBA-NEXT: snez a2, a2 1920; RV64ZBA-NEXT: sh2add a0, a3, a0 1921; RV64ZBA-NEXT: sd a0, 0(a1) 1922; RV64ZBA-NEXT: mv a0, a2 1923; RV64ZBA-NEXT: ret 1924; 1925; RV32ZICOND-LABEL: umulo2.i64: 1926; RV32ZICOND: # %bb.0: # %entry 1927; RV32ZICOND-NEXT: li a3, 13 1928; RV32ZICOND-NEXT: mul a4, a1, a3 1929; RV32ZICOND-NEXT: mulhu a5, a0, a3 1930; RV32ZICOND-NEXT: mulhu a1, a1, a3 1931; RV32ZICOND-NEXT: mul a3, a0, a3 1932; RV32ZICOND-NEXT: add a4, a5, a4 1933; RV32ZICOND-NEXT: snez a0, a1 1934; RV32ZICOND-NEXT: sltu a1, a4, a5 1935; RV32ZICOND-NEXT: or a0, a0, a1 1936; RV32ZICOND-NEXT: sw a3, 0(a2) 1937; RV32ZICOND-NEXT: sw a4, 4(a2) 1938; RV32ZICOND-NEXT: ret 1939; 1940; RV64ZICOND-LABEL: umulo2.i64: 1941; RV64ZICOND: # %bb.0: # %entry 1942; RV64ZICOND-NEXT: li a3, 13 1943; RV64ZICOND-NEXT: mulhu a2, a0, a3 1944; RV64ZICOND-NEXT: snez a2, a2 1945; RV64ZICOND-NEXT: mul a0, a0, a3 1946; RV64ZICOND-NEXT: sd a0, 0(a1) 1947; RV64ZICOND-NEXT: mv a0, a2 1948; RV64ZICOND-NEXT: ret 1949entry: 1950 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 13) 1951 %val = extractvalue {i64, i1} %t, 0 1952 %obit = extractvalue {i64, i1} %t, 1 1953 store i64 %val, ptr %res 1954 ret i1 %obit 1955} 1956 1957 1958; 1959; Check the use of the overflow bit in combination with a select instruction. 1960; 1961define i32 @saddo.select.i32(i32 signext %v1, i32 signext %v2) { 1962; RV32-LABEL: saddo.select.i32: 1963; RV32: # %bb.0: # %entry 1964; RV32-NEXT: add a2, a0, a1 1965; RV32-NEXT: slt a2, a2, a0 1966; RV32-NEXT: slti a3, a1, 0 1967; RV32-NEXT: bne a3, a2, .LBB28_2 1968; RV32-NEXT: # %bb.1: # %entry 1969; RV32-NEXT: mv a0, a1 1970; RV32-NEXT: .LBB28_2: # %entry 1971; RV32-NEXT: ret 1972; 1973; RV64-LABEL: saddo.select.i32: 1974; RV64: # %bb.0: # %entry 1975; RV64-NEXT: add a2, a0, a1 1976; RV64-NEXT: addw a3, a0, a1 1977; RV64-NEXT: bne a3, a2, .LBB28_2 1978; RV64-NEXT: # %bb.1: # %entry 1979; RV64-NEXT: mv a0, a1 1980; RV64-NEXT: .LBB28_2: # %entry 1981; RV64-NEXT: ret 1982; 1983; RV32ZBA-LABEL: saddo.select.i32: 1984; RV32ZBA: # %bb.0: # %entry 1985; RV32ZBA-NEXT: add a2, a0, a1 1986; RV32ZBA-NEXT: slt a2, a2, a0 1987; RV32ZBA-NEXT: slti a3, a1, 0 1988; RV32ZBA-NEXT: bne a3, a2, .LBB28_2 1989; RV32ZBA-NEXT: # %bb.1: # %entry 1990; RV32ZBA-NEXT: mv a0, a1 1991; RV32ZBA-NEXT: .LBB28_2: # %entry 1992; RV32ZBA-NEXT: ret 1993; 1994; RV64ZBA-LABEL: saddo.select.i32: 1995; RV64ZBA: # %bb.0: # %entry 1996; RV64ZBA-NEXT: add a2, a0, a1 1997; RV64ZBA-NEXT: addw a3, a0, a1 1998; RV64ZBA-NEXT: bne a3, a2, .LBB28_2 1999; RV64ZBA-NEXT: # %bb.1: # %entry 2000; RV64ZBA-NEXT: mv a0, a1 2001; RV64ZBA-NEXT: .LBB28_2: # %entry 2002; RV64ZBA-NEXT: ret 2003; 2004; RV32ZICOND-LABEL: saddo.select.i32: 2005; RV32ZICOND: # %bb.0: # %entry 2006; RV32ZICOND-NEXT: add a2, a0, a1 2007; RV32ZICOND-NEXT: slti a3, a1, 0 2008; RV32ZICOND-NEXT: slt a2, a2, a0 2009; RV32ZICOND-NEXT: xor a2, a3, a2 2010; RV32ZICOND-NEXT: czero.nez a1, a1, a2 2011; RV32ZICOND-NEXT: czero.eqz a0, a0, a2 2012; RV32ZICOND-NEXT: or a0, a0, a1 2013; RV32ZICOND-NEXT: ret 2014; 2015; RV64ZICOND-LABEL: saddo.select.i32: 2016; RV64ZICOND: # %bb.0: # %entry 2017; RV64ZICOND-NEXT: add a2, a0, a1 2018; RV64ZICOND-NEXT: addw a3, a0, a1 2019; RV64ZICOND-NEXT: xor a2, a3, a2 2020; RV64ZICOND-NEXT: czero.nez a1, a1, a2 2021; RV64ZICOND-NEXT: czero.eqz a0, a0, a2 2022; RV64ZICOND-NEXT: or a0, a0, a1 2023; RV64ZICOND-NEXT: ret 2024entry: 2025 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2) 2026 %obit = extractvalue {i32, i1} %t, 1 2027 %ret = select i1 %obit, i32 %v1, i32 %v2 2028 ret i32 %ret 2029} 2030 2031define i1 @saddo.not.i32(i32 signext %v1, i32 signext %v2) { 2032; RV32-LABEL: saddo.not.i32: 2033; RV32: # %bb.0: # %entry 2034; RV32-NEXT: add a2, a0, a1 2035; RV32-NEXT: slt a0, a2, a0 2036; RV32-NEXT: slti a1, a1, 0 2037; RV32-NEXT: xor a0, a1, a0 2038; RV32-NEXT: xori a0, a0, 1 2039; RV32-NEXT: ret 2040; 2041; RV64-LABEL: saddo.not.i32: 2042; RV64: # %bb.0: # %entry 2043; RV64-NEXT: add a2, a0, a1 2044; RV64-NEXT: addw a0, a0, a1 2045; RV64-NEXT: xor a0, a0, a2 2046; RV64-NEXT: seqz a0, a0 2047; RV64-NEXT: ret 2048; 2049; RV32ZBA-LABEL: saddo.not.i32: 2050; RV32ZBA: # %bb.0: # %entry 2051; RV32ZBA-NEXT: add a2, a0, a1 2052; RV32ZBA-NEXT: slt a0, a2, a0 2053; RV32ZBA-NEXT: slti a1, a1, 0 2054; RV32ZBA-NEXT: xor a0, a1, a0 2055; RV32ZBA-NEXT: xori a0, a0, 1 2056; RV32ZBA-NEXT: ret 2057; 2058; RV64ZBA-LABEL: saddo.not.i32: 2059; RV64ZBA: # %bb.0: # %entry 2060; RV64ZBA-NEXT: add a2, a0, a1 2061; RV64ZBA-NEXT: addw a0, a0, a1 2062; RV64ZBA-NEXT: xor a0, a0, a2 2063; RV64ZBA-NEXT: seqz a0, a0 2064; RV64ZBA-NEXT: ret 2065; 2066; RV32ZICOND-LABEL: saddo.not.i32: 2067; RV32ZICOND: # %bb.0: # %entry 2068; RV32ZICOND-NEXT: add a2, a0, a1 2069; RV32ZICOND-NEXT: slt a0, a2, a0 2070; RV32ZICOND-NEXT: slti a1, a1, 0 2071; RV32ZICOND-NEXT: xor a0, a1, a0 2072; RV32ZICOND-NEXT: xori a0, a0, 1 2073; RV32ZICOND-NEXT: ret 2074; 2075; RV64ZICOND-LABEL: saddo.not.i32: 2076; RV64ZICOND: # %bb.0: # %entry 2077; RV64ZICOND-NEXT: add a2, a0, a1 2078; RV64ZICOND-NEXT: addw a0, a0, a1 2079; RV64ZICOND-NEXT: xor a0, a0, a2 2080; RV64ZICOND-NEXT: seqz a0, a0 2081; RV64ZICOND-NEXT: ret 2082entry: 2083 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2) 2084 %obit = extractvalue {i32, i1} %t, 1 2085 %ret = xor i1 %obit, true 2086 ret i1 %ret 2087} 2088 2089define i64 @saddo.select.i64(i64 %v1, i64 %v2) { 2090; RV32-LABEL: saddo.select.i64: 2091; RV32: # %bb.0: # %entry 2092; RV32-NEXT: add a4, a1, a3 2093; RV32-NEXT: add a5, a0, a2 2094; RV32-NEXT: sltu a5, a5, a0 2095; RV32-NEXT: add a4, a4, a5 2096; RV32-NEXT: xor a5, a1, a3 2097; RV32-NEXT: xor a4, a1, a4 2098; RV32-NEXT: not a5, a5 2099; RV32-NEXT: and a4, a5, a4 2100; RV32-NEXT: bltz a4, .LBB30_2 2101; RV32-NEXT: # %bb.1: # %entry 2102; RV32-NEXT: mv a0, a2 2103; RV32-NEXT: mv a1, a3 2104; RV32-NEXT: .LBB30_2: # %entry 2105; RV32-NEXT: ret 2106; 2107; RV64-LABEL: saddo.select.i64: 2108; RV64: # %bb.0: # %entry 2109; RV64-NEXT: add a2, a0, a1 2110; RV64-NEXT: slt a2, a2, a0 2111; RV64-NEXT: slti a3, a1, 0 2112; RV64-NEXT: bne a3, a2, .LBB30_2 2113; RV64-NEXT: # %bb.1: # %entry 2114; RV64-NEXT: mv a0, a1 2115; RV64-NEXT: .LBB30_2: # %entry 2116; RV64-NEXT: ret 2117; 2118; RV32ZBA-LABEL: saddo.select.i64: 2119; RV32ZBA: # %bb.0: # %entry 2120; RV32ZBA-NEXT: add a4, a1, a3 2121; RV32ZBA-NEXT: add a5, a0, a2 2122; RV32ZBA-NEXT: sltu a5, a5, a0 2123; RV32ZBA-NEXT: add a4, a4, a5 2124; RV32ZBA-NEXT: xor a5, a1, a3 2125; RV32ZBA-NEXT: xor a4, a1, a4 2126; RV32ZBA-NEXT: not a5, a5 2127; RV32ZBA-NEXT: and a4, a5, a4 2128; RV32ZBA-NEXT: bltz a4, .LBB30_2 2129; RV32ZBA-NEXT: # %bb.1: # %entry 2130; RV32ZBA-NEXT: mv a0, a2 2131; RV32ZBA-NEXT: mv a1, a3 2132; RV32ZBA-NEXT: .LBB30_2: # %entry 2133; RV32ZBA-NEXT: ret 2134; 2135; RV64ZBA-LABEL: saddo.select.i64: 2136; RV64ZBA: # %bb.0: # %entry 2137; RV64ZBA-NEXT: add a2, a0, a1 2138; RV64ZBA-NEXT: slt a2, a2, a0 2139; RV64ZBA-NEXT: slti a3, a1, 0 2140; RV64ZBA-NEXT: bne a3, a2, .LBB30_2 2141; RV64ZBA-NEXT: # %bb.1: # %entry 2142; RV64ZBA-NEXT: mv a0, a1 2143; RV64ZBA-NEXT: .LBB30_2: # %entry 2144; RV64ZBA-NEXT: ret 2145; 2146; RV32ZICOND-LABEL: saddo.select.i64: 2147; RV32ZICOND: # %bb.0: # %entry 2148; RV32ZICOND-NEXT: add a4, a1, a3 2149; RV32ZICOND-NEXT: add a5, a0, a2 2150; RV32ZICOND-NEXT: sltu a5, a5, a0 2151; RV32ZICOND-NEXT: add a4, a4, a5 2152; RV32ZICOND-NEXT: xor a5, a1, a3 2153; RV32ZICOND-NEXT: not a5, a5 2154; RV32ZICOND-NEXT: xor a4, a1, a4 2155; RV32ZICOND-NEXT: and a4, a5, a4 2156; RV32ZICOND-NEXT: slti a4, a4, 0 2157; RV32ZICOND-NEXT: czero.nez a2, a2, a4 2158; RV32ZICOND-NEXT: czero.eqz a0, a0, a4 2159; RV32ZICOND-NEXT: czero.nez a3, a3, a4 2160; RV32ZICOND-NEXT: czero.eqz a1, a1, a4 2161; RV32ZICOND-NEXT: or a0, a0, a2 2162; RV32ZICOND-NEXT: or a1, a1, a3 2163; RV32ZICOND-NEXT: ret 2164; 2165; RV64ZICOND-LABEL: saddo.select.i64: 2166; RV64ZICOND: # %bb.0: # %entry 2167; RV64ZICOND-NEXT: add a2, a0, a1 2168; RV64ZICOND-NEXT: slti a3, a1, 0 2169; RV64ZICOND-NEXT: slt a2, a2, a0 2170; RV64ZICOND-NEXT: xor a2, a3, a2 2171; RV64ZICOND-NEXT: czero.nez a1, a1, a2 2172; RV64ZICOND-NEXT: czero.eqz a0, a0, a2 2173; RV64ZICOND-NEXT: or a0, a0, a1 2174; RV64ZICOND-NEXT: ret 2175entry: 2176 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2) 2177 %obit = extractvalue {i64, i1} %t, 1 2178 %ret = select i1 %obit, i64 %v1, i64 %v2 2179 ret i64 %ret 2180} 2181 2182define i1 @saddo.not.i64(i64 %v1, i64 %v2) { 2183; RV32-LABEL: saddo.not.i64: 2184; RV32: # %bb.0: # %entry 2185; RV32-NEXT: add a4, a1, a3 2186; RV32-NEXT: add a2, a0, a2 2187; RV32-NEXT: xor a3, a1, a3 2188; RV32-NEXT: sltu a0, a2, a0 2189; RV32-NEXT: add a0, a4, a0 2190; RV32-NEXT: xor a0, a1, a0 2191; RV32-NEXT: not a1, a3 2192; RV32-NEXT: and a0, a1, a0 2193; RV32-NEXT: slti a0, a0, 0 2194; RV32-NEXT: xori a0, a0, 1 2195; RV32-NEXT: ret 2196; 2197; RV64-LABEL: saddo.not.i64: 2198; RV64: # %bb.0: # %entry 2199; RV64-NEXT: add a2, a0, a1 2200; RV64-NEXT: slt a0, a2, a0 2201; RV64-NEXT: slti a1, a1, 0 2202; RV64-NEXT: xor a0, a1, a0 2203; RV64-NEXT: xori a0, a0, 1 2204; RV64-NEXT: ret 2205; 2206; RV32ZBA-LABEL: saddo.not.i64: 2207; RV32ZBA: # %bb.0: # %entry 2208; RV32ZBA-NEXT: add a4, a1, a3 2209; RV32ZBA-NEXT: add a2, a0, a2 2210; RV32ZBA-NEXT: xor a3, a1, a3 2211; RV32ZBA-NEXT: sltu a0, a2, a0 2212; RV32ZBA-NEXT: add a0, a4, a0 2213; RV32ZBA-NEXT: xor a0, a1, a0 2214; RV32ZBA-NEXT: not a1, a3 2215; RV32ZBA-NEXT: and a0, a1, a0 2216; RV32ZBA-NEXT: slti a0, a0, 0 2217; RV32ZBA-NEXT: xori a0, a0, 1 2218; RV32ZBA-NEXT: ret 2219; 2220; RV64ZBA-LABEL: saddo.not.i64: 2221; RV64ZBA: # %bb.0: # %entry 2222; RV64ZBA-NEXT: add a2, a0, a1 2223; RV64ZBA-NEXT: slt a0, a2, a0 2224; RV64ZBA-NEXT: slti a1, a1, 0 2225; RV64ZBA-NEXT: xor a0, a1, a0 2226; RV64ZBA-NEXT: xori a0, a0, 1 2227; RV64ZBA-NEXT: ret 2228; 2229; RV32ZICOND-LABEL: saddo.not.i64: 2230; RV32ZICOND: # %bb.0: # %entry 2231; RV32ZICOND-NEXT: add a4, a1, a3 2232; RV32ZICOND-NEXT: add a2, a0, a2 2233; RV32ZICOND-NEXT: xor a3, a1, a3 2234; RV32ZICOND-NEXT: sltu a0, a2, a0 2235; RV32ZICOND-NEXT: add a0, a4, a0 2236; RV32ZICOND-NEXT: xor a0, a1, a0 2237; RV32ZICOND-NEXT: not a1, a3 2238; RV32ZICOND-NEXT: and a0, a1, a0 2239; RV32ZICOND-NEXT: slti a0, a0, 0 2240; RV32ZICOND-NEXT: xori a0, a0, 1 2241; RV32ZICOND-NEXT: ret 2242; 2243; RV64ZICOND-LABEL: saddo.not.i64: 2244; RV64ZICOND: # %bb.0: # %entry 2245; RV64ZICOND-NEXT: add a2, a0, a1 2246; RV64ZICOND-NEXT: slt a0, a2, a0 2247; RV64ZICOND-NEXT: slti a1, a1, 0 2248; RV64ZICOND-NEXT: xor a0, a1, a0 2249; RV64ZICOND-NEXT: xori a0, a0, 1 2250; RV64ZICOND-NEXT: ret 2251entry: 2252 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2) 2253 %obit = extractvalue {i64, i1} %t, 1 2254 %ret = xor i1 %obit, true 2255 ret i1 %ret 2256} 2257 2258define i32 @uaddo.select.i32(i32 signext %v1, i32 signext %v2) { 2259; RV32-LABEL: uaddo.select.i32: 2260; RV32: # %bb.0: # %entry 2261; RV32-NEXT: add a2, a0, a1 2262; RV32-NEXT: bltu a2, a0, .LBB32_2 2263; RV32-NEXT: # %bb.1: # %entry 2264; RV32-NEXT: mv a0, a1 2265; RV32-NEXT: .LBB32_2: # %entry 2266; RV32-NEXT: ret 2267; 2268; RV64-LABEL: uaddo.select.i32: 2269; RV64: # %bb.0: # %entry 2270; RV64-NEXT: addw a2, a0, a1 2271; RV64-NEXT: bltu a2, a0, .LBB32_2 2272; RV64-NEXT: # %bb.1: # %entry 2273; RV64-NEXT: mv a0, a1 2274; RV64-NEXT: .LBB32_2: # %entry 2275; RV64-NEXT: ret 2276; 2277; RV32ZBA-LABEL: uaddo.select.i32: 2278; RV32ZBA: # %bb.0: # %entry 2279; RV32ZBA-NEXT: add a2, a0, a1 2280; RV32ZBA-NEXT: bltu a2, a0, .LBB32_2 2281; RV32ZBA-NEXT: # %bb.1: # %entry 2282; RV32ZBA-NEXT: mv a0, a1 2283; RV32ZBA-NEXT: .LBB32_2: # %entry 2284; RV32ZBA-NEXT: ret 2285; 2286; RV64ZBA-LABEL: uaddo.select.i32: 2287; RV64ZBA: # %bb.0: # %entry 2288; RV64ZBA-NEXT: addw a2, a0, a1 2289; RV64ZBA-NEXT: bltu a2, a0, .LBB32_2 2290; RV64ZBA-NEXT: # %bb.1: # %entry 2291; RV64ZBA-NEXT: mv a0, a1 2292; RV64ZBA-NEXT: .LBB32_2: # %entry 2293; RV64ZBA-NEXT: ret 2294; 2295; RV32ZICOND-LABEL: uaddo.select.i32: 2296; RV32ZICOND: # %bb.0: # %entry 2297; RV32ZICOND-NEXT: add a2, a0, a1 2298; RV32ZICOND-NEXT: sltu a2, a2, a0 2299; RV32ZICOND-NEXT: czero.nez a1, a1, a2 2300; RV32ZICOND-NEXT: czero.eqz a0, a0, a2 2301; RV32ZICOND-NEXT: or a0, a0, a1 2302; RV32ZICOND-NEXT: ret 2303; 2304; RV64ZICOND-LABEL: uaddo.select.i32: 2305; RV64ZICOND: # %bb.0: # %entry 2306; RV64ZICOND-NEXT: addw a2, a0, a1 2307; RV64ZICOND-NEXT: sltu a2, a2, a0 2308; RV64ZICOND-NEXT: czero.nez a1, a1, a2 2309; RV64ZICOND-NEXT: czero.eqz a0, a0, a2 2310; RV64ZICOND-NEXT: or a0, a0, a1 2311; RV64ZICOND-NEXT: ret 2312entry: 2313 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2) 2314 %obit = extractvalue {i32, i1} %t, 1 2315 %ret = select i1 %obit, i32 %v1, i32 %v2 2316 ret i32 %ret 2317} 2318 2319define i1 @uaddo.not.i32(i32 signext %v1, i32 signext %v2) { 2320; RV32-LABEL: uaddo.not.i32: 2321; RV32: # %bb.0: # %entry 2322; RV32-NEXT: add a1, a0, a1 2323; RV32-NEXT: sltu a0, a1, a0 2324; RV32-NEXT: xori a0, a0, 1 2325; RV32-NEXT: ret 2326; 2327; RV64-LABEL: uaddo.not.i32: 2328; RV64: # %bb.0: # %entry 2329; RV64-NEXT: addw a1, a0, a1 2330; RV64-NEXT: sltu a0, a1, a0 2331; RV64-NEXT: xori a0, a0, 1 2332; RV64-NEXT: ret 2333; 2334; RV32ZBA-LABEL: uaddo.not.i32: 2335; RV32ZBA: # %bb.0: # %entry 2336; RV32ZBA-NEXT: add a1, a0, a1 2337; RV32ZBA-NEXT: sltu a0, a1, a0 2338; RV32ZBA-NEXT: xori a0, a0, 1 2339; RV32ZBA-NEXT: ret 2340; 2341; RV64ZBA-LABEL: uaddo.not.i32: 2342; RV64ZBA: # %bb.0: # %entry 2343; RV64ZBA-NEXT: addw a1, a0, a1 2344; RV64ZBA-NEXT: sltu a0, a1, a0 2345; RV64ZBA-NEXT: xori a0, a0, 1 2346; RV64ZBA-NEXT: ret 2347; 2348; RV32ZICOND-LABEL: uaddo.not.i32: 2349; RV32ZICOND: # %bb.0: # %entry 2350; RV32ZICOND-NEXT: add a1, a0, a1 2351; RV32ZICOND-NEXT: sltu a0, a1, a0 2352; RV32ZICOND-NEXT: xori a0, a0, 1 2353; RV32ZICOND-NEXT: ret 2354; 2355; RV64ZICOND-LABEL: uaddo.not.i32: 2356; RV64ZICOND: # %bb.0: # %entry 2357; RV64ZICOND-NEXT: addw a1, a0, a1 2358; RV64ZICOND-NEXT: sltu a0, a1, a0 2359; RV64ZICOND-NEXT: xori a0, a0, 1 2360; RV64ZICOND-NEXT: ret 2361entry: 2362 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2) 2363 %obit = extractvalue {i32, i1} %t, 1 2364 %ret = xor i1 %obit, true 2365 ret i1 %ret 2366} 2367 2368define i64 @uaddo.select.i64(i64 %v1, i64 %v2) { 2369; RV32-LABEL: uaddo.select.i64: 2370; RV32: # %bb.0: # %entry 2371; RV32-NEXT: add a5, a1, a3 2372; RV32-NEXT: add a4, a0, a2 2373; RV32-NEXT: sltu a4, a4, a0 2374; RV32-NEXT: add a5, a5, a4 2375; RV32-NEXT: bne a5, a1, .LBB34_3 2376; RV32-NEXT: # %bb.1: # %entry 2377; RV32-NEXT: beqz a4, .LBB34_4 2378; RV32-NEXT: .LBB34_2: # %entry 2379; RV32-NEXT: ret 2380; RV32-NEXT: .LBB34_3: # %entry 2381; RV32-NEXT: sltu a4, a5, a1 2382; RV32-NEXT: bnez a4, .LBB34_2 2383; RV32-NEXT: .LBB34_4: # %entry 2384; RV32-NEXT: mv a0, a2 2385; RV32-NEXT: mv a1, a3 2386; RV32-NEXT: ret 2387; 2388; RV64-LABEL: uaddo.select.i64: 2389; RV64: # %bb.0: # %entry 2390; RV64-NEXT: add a2, a0, a1 2391; RV64-NEXT: bltu a2, a0, .LBB34_2 2392; RV64-NEXT: # %bb.1: # %entry 2393; RV64-NEXT: mv a0, a1 2394; RV64-NEXT: .LBB34_2: # %entry 2395; RV64-NEXT: ret 2396; 2397; RV32ZBA-LABEL: uaddo.select.i64: 2398; RV32ZBA: # %bb.0: # %entry 2399; RV32ZBA-NEXT: add a5, a1, a3 2400; RV32ZBA-NEXT: add a4, a0, a2 2401; RV32ZBA-NEXT: sltu a4, a4, a0 2402; RV32ZBA-NEXT: add a5, a5, a4 2403; RV32ZBA-NEXT: bne a5, a1, .LBB34_3 2404; RV32ZBA-NEXT: # %bb.1: # %entry 2405; RV32ZBA-NEXT: beqz a4, .LBB34_4 2406; RV32ZBA-NEXT: .LBB34_2: # %entry 2407; RV32ZBA-NEXT: ret 2408; RV32ZBA-NEXT: .LBB34_3: # %entry 2409; RV32ZBA-NEXT: sltu a4, a5, a1 2410; RV32ZBA-NEXT: bnez a4, .LBB34_2 2411; RV32ZBA-NEXT: .LBB34_4: # %entry 2412; RV32ZBA-NEXT: mv a0, a2 2413; RV32ZBA-NEXT: mv a1, a3 2414; RV32ZBA-NEXT: ret 2415; 2416; RV64ZBA-LABEL: uaddo.select.i64: 2417; RV64ZBA: # %bb.0: # %entry 2418; RV64ZBA-NEXT: add a2, a0, a1 2419; RV64ZBA-NEXT: bltu a2, a0, .LBB34_2 2420; RV64ZBA-NEXT: # %bb.1: # %entry 2421; RV64ZBA-NEXT: mv a0, a1 2422; RV64ZBA-NEXT: .LBB34_2: # %entry 2423; RV64ZBA-NEXT: ret 2424; 2425; RV32ZICOND-LABEL: uaddo.select.i64: 2426; RV32ZICOND: # %bb.0: # %entry 2427; RV32ZICOND-NEXT: add a4, a1, a3 2428; RV32ZICOND-NEXT: add a5, a0, a2 2429; RV32ZICOND-NEXT: sltu a5, a5, a0 2430; RV32ZICOND-NEXT: add a4, a4, a5 2431; RV32ZICOND-NEXT: xor a6, a4, a1 2432; RV32ZICOND-NEXT: sltu a4, a4, a1 2433; RV32ZICOND-NEXT: czero.eqz a4, a4, a6 2434; RV32ZICOND-NEXT: czero.nez a5, a5, a6 2435; RV32ZICOND-NEXT: or a4, a5, a4 2436; RV32ZICOND-NEXT: czero.nez a2, a2, a4 2437; RV32ZICOND-NEXT: czero.eqz a0, a0, a4 2438; RV32ZICOND-NEXT: czero.nez a3, a3, a4 2439; RV32ZICOND-NEXT: czero.eqz a1, a1, a4 2440; RV32ZICOND-NEXT: or a0, a0, a2 2441; RV32ZICOND-NEXT: or a1, a1, a3 2442; RV32ZICOND-NEXT: ret 2443; 2444; RV64ZICOND-LABEL: uaddo.select.i64: 2445; RV64ZICOND: # %bb.0: # %entry 2446; RV64ZICOND-NEXT: add a2, a0, a1 2447; RV64ZICOND-NEXT: sltu a2, a2, a0 2448; RV64ZICOND-NEXT: czero.nez a1, a1, a2 2449; RV64ZICOND-NEXT: czero.eqz a0, a0, a2 2450; RV64ZICOND-NEXT: or a0, a0, a1 2451; RV64ZICOND-NEXT: ret 2452entry: 2453 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2) 2454 %obit = extractvalue {i64, i1} %t, 1 2455 %ret = select i1 %obit, i64 %v1, i64 %v2 2456 ret i64 %ret 2457} 2458 2459define i1 @uaddo.not.i64(i64 %v1, i64 %v2) { 2460; RV32-LABEL: uaddo.not.i64: 2461; RV32: # %bb.0: # %entry 2462; RV32-NEXT: add a3, a1, a3 2463; RV32-NEXT: add a2, a0, a2 2464; RV32-NEXT: sltu a0, a2, a0 2465; RV32-NEXT: add a2, a3, a0 2466; RV32-NEXT: beq a2, a1, .LBB35_2 2467; RV32-NEXT: # %bb.1: # %entry 2468; RV32-NEXT: sltu a0, a2, a1 2469; RV32-NEXT: .LBB35_2: # %entry 2470; RV32-NEXT: xori a0, a0, 1 2471; RV32-NEXT: ret 2472; 2473; RV64-LABEL: uaddo.not.i64: 2474; RV64: # %bb.0: # %entry 2475; RV64-NEXT: add a1, a0, a1 2476; RV64-NEXT: sltu a0, a1, a0 2477; RV64-NEXT: xori a0, a0, 1 2478; RV64-NEXT: ret 2479; 2480; RV32ZBA-LABEL: uaddo.not.i64: 2481; RV32ZBA: # %bb.0: # %entry 2482; RV32ZBA-NEXT: add a3, a1, a3 2483; RV32ZBA-NEXT: add a2, a0, a2 2484; RV32ZBA-NEXT: sltu a0, a2, a0 2485; RV32ZBA-NEXT: add a2, a3, a0 2486; RV32ZBA-NEXT: beq a2, a1, .LBB35_2 2487; RV32ZBA-NEXT: # %bb.1: # %entry 2488; RV32ZBA-NEXT: sltu a0, a2, a1 2489; RV32ZBA-NEXT: .LBB35_2: # %entry 2490; RV32ZBA-NEXT: xori a0, a0, 1 2491; RV32ZBA-NEXT: ret 2492; 2493; RV64ZBA-LABEL: uaddo.not.i64: 2494; RV64ZBA: # %bb.0: # %entry 2495; RV64ZBA-NEXT: add a1, a0, a1 2496; RV64ZBA-NEXT: sltu a0, a1, a0 2497; RV64ZBA-NEXT: xori a0, a0, 1 2498; RV64ZBA-NEXT: ret 2499; 2500; RV32ZICOND-LABEL: uaddo.not.i64: 2501; RV32ZICOND: # %bb.0: # %entry 2502; RV32ZICOND-NEXT: add a3, a1, a3 2503; RV32ZICOND-NEXT: add a2, a0, a2 2504; RV32ZICOND-NEXT: sltu a0, a2, a0 2505; RV32ZICOND-NEXT: add a3, a3, a0 2506; RV32ZICOND-NEXT: xor a2, a3, a1 2507; RV32ZICOND-NEXT: sltu a1, a3, a1 2508; RV32ZICOND-NEXT: czero.eqz a1, a1, a2 2509; RV32ZICOND-NEXT: czero.nez a0, a0, a2 2510; RV32ZICOND-NEXT: or a0, a0, a1 2511; RV32ZICOND-NEXT: xori a0, a0, 1 2512; RV32ZICOND-NEXT: ret 2513; 2514; RV64ZICOND-LABEL: uaddo.not.i64: 2515; RV64ZICOND: # %bb.0: # %entry 2516; RV64ZICOND-NEXT: add a1, a0, a1 2517; RV64ZICOND-NEXT: sltu a0, a1, a0 2518; RV64ZICOND-NEXT: xori a0, a0, 1 2519; RV64ZICOND-NEXT: ret 2520entry: 2521 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2) 2522 %obit = extractvalue {i64, i1} %t, 1 2523 %ret = xor i1 %obit, true 2524 ret i1 %ret 2525} 2526 2527define i32 @ssubo.select.i32(i32 signext %v1, i32 signext %v2) { 2528; RV32-LABEL: ssubo.select.i32: 2529; RV32: # %bb.0: # %entry 2530; RV32-NEXT: sgtz a2, a1 2531; RV32-NEXT: sub a3, a0, a1 2532; RV32-NEXT: slt a3, a3, a0 2533; RV32-NEXT: bne a2, a3, .LBB36_2 2534; RV32-NEXT: # %bb.1: # %entry 2535; RV32-NEXT: mv a0, a1 2536; RV32-NEXT: .LBB36_2: # %entry 2537; RV32-NEXT: ret 2538; 2539; RV64-LABEL: ssubo.select.i32: 2540; RV64: # %bb.0: # %entry 2541; RV64-NEXT: sub a2, a0, a1 2542; RV64-NEXT: subw a3, a0, a1 2543; RV64-NEXT: bne a3, a2, .LBB36_2 2544; RV64-NEXT: # %bb.1: # %entry 2545; RV64-NEXT: mv a0, a1 2546; RV64-NEXT: .LBB36_2: # %entry 2547; RV64-NEXT: ret 2548; 2549; RV32ZBA-LABEL: ssubo.select.i32: 2550; RV32ZBA: # %bb.0: # %entry 2551; RV32ZBA-NEXT: sgtz a2, a1 2552; RV32ZBA-NEXT: sub a3, a0, a1 2553; RV32ZBA-NEXT: slt a3, a3, a0 2554; RV32ZBA-NEXT: bne a2, a3, .LBB36_2 2555; RV32ZBA-NEXT: # %bb.1: # %entry 2556; RV32ZBA-NEXT: mv a0, a1 2557; RV32ZBA-NEXT: .LBB36_2: # %entry 2558; RV32ZBA-NEXT: ret 2559; 2560; RV64ZBA-LABEL: ssubo.select.i32: 2561; RV64ZBA: # %bb.0: # %entry 2562; RV64ZBA-NEXT: sub a2, a0, a1 2563; RV64ZBA-NEXT: subw a3, a0, a1 2564; RV64ZBA-NEXT: bne a3, a2, .LBB36_2 2565; RV64ZBA-NEXT: # %bb.1: # %entry 2566; RV64ZBA-NEXT: mv a0, a1 2567; RV64ZBA-NEXT: .LBB36_2: # %entry 2568; RV64ZBA-NEXT: ret 2569; 2570; RV32ZICOND-LABEL: ssubo.select.i32: 2571; RV32ZICOND: # %bb.0: # %entry 2572; RV32ZICOND-NEXT: sgtz a2, a1 2573; RV32ZICOND-NEXT: sub a3, a0, a1 2574; RV32ZICOND-NEXT: slt a3, a3, a0 2575; RV32ZICOND-NEXT: xor a2, a2, a3 2576; RV32ZICOND-NEXT: czero.nez a1, a1, a2 2577; RV32ZICOND-NEXT: czero.eqz a0, a0, a2 2578; RV32ZICOND-NEXT: or a0, a0, a1 2579; RV32ZICOND-NEXT: ret 2580; 2581; RV64ZICOND-LABEL: ssubo.select.i32: 2582; RV64ZICOND: # %bb.0: # %entry 2583; RV64ZICOND-NEXT: sub a2, a0, a1 2584; RV64ZICOND-NEXT: subw a3, a0, a1 2585; RV64ZICOND-NEXT: xor a2, a3, a2 2586; RV64ZICOND-NEXT: czero.nez a1, a1, a2 2587; RV64ZICOND-NEXT: czero.eqz a0, a0, a2 2588; RV64ZICOND-NEXT: or a0, a0, a1 2589; RV64ZICOND-NEXT: ret 2590entry: 2591 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2) 2592 %obit = extractvalue {i32, i1} %t, 1 2593 %ret = select i1 %obit, i32 %v1, i32 %v2 2594 ret i32 %ret 2595} 2596 2597define i1 @ssubo.not.i32(i32 signext %v1, i32 signext %v2) { 2598; RV32-LABEL: ssubo.not.i32: 2599; RV32: # %bb.0: # %entry 2600; RV32-NEXT: sgtz a2, a1 2601; RV32-NEXT: sub a1, a0, a1 2602; RV32-NEXT: slt a0, a1, a0 2603; RV32-NEXT: xor a0, a2, a0 2604; RV32-NEXT: xori a0, a0, 1 2605; RV32-NEXT: ret 2606; 2607; RV64-LABEL: ssubo.not.i32: 2608; RV64: # %bb.0: # %entry 2609; RV64-NEXT: sub a2, a0, a1 2610; RV64-NEXT: subw a0, a0, a1 2611; RV64-NEXT: xor a0, a0, a2 2612; RV64-NEXT: seqz a0, a0 2613; RV64-NEXT: ret 2614; 2615; RV32ZBA-LABEL: ssubo.not.i32: 2616; RV32ZBA: # %bb.0: # %entry 2617; RV32ZBA-NEXT: sgtz a2, a1 2618; RV32ZBA-NEXT: sub a1, a0, a1 2619; RV32ZBA-NEXT: slt a0, a1, a0 2620; RV32ZBA-NEXT: xor a0, a2, a0 2621; RV32ZBA-NEXT: xori a0, a0, 1 2622; RV32ZBA-NEXT: ret 2623; 2624; RV64ZBA-LABEL: ssubo.not.i32: 2625; RV64ZBA: # %bb.0: # %entry 2626; RV64ZBA-NEXT: sub a2, a0, a1 2627; RV64ZBA-NEXT: subw a0, a0, a1 2628; RV64ZBA-NEXT: xor a0, a0, a2 2629; RV64ZBA-NEXT: seqz a0, a0 2630; RV64ZBA-NEXT: ret 2631; 2632; RV32ZICOND-LABEL: ssubo.not.i32: 2633; RV32ZICOND: # %bb.0: # %entry 2634; RV32ZICOND-NEXT: sgtz a2, a1 2635; RV32ZICOND-NEXT: sub a1, a0, a1 2636; RV32ZICOND-NEXT: slt a0, a1, a0 2637; RV32ZICOND-NEXT: xor a0, a2, a0 2638; RV32ZICOND-NEXT: xori a0, a0, 1 2639; RV32ZICOND-NEXT: ret 2640; 2641; RV64ZICOND-LABEL: ssubo.not.i32: 2642; RV64ZICOND: # %bb.0: # %entry 2643; RV64ZICOND-NEXT: sub a2, a0, a1 2644; RV64ZICOND-NEXT: subw a0, a0, a1 2645; RV64ZICOND-NEXT: xor a0, a0, a2 2646; RV64ZICOND-NEXT: seqz a0, a0 2647; RV64ZICOND-NEXT: ret 2648entry: 2649 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2) 2650 %obit = extractvalue {i32, i1} %t, 1 2651 %ret = xor i1 %obit, true 2652 ret i1 %ret 2653} 2654 2655define i64 @ssubo.select.i64(i64 %v1, i64 %v2) { 2656; RV32-LABEL: ssubo.select.i64: 2657; RV32: # %bb.0: # %entry 2658; RV32-NEXT: sltu a4, a0, a2 2659; RV32-NEXT: sub a5, a1, a3 2660; RV32-NEXT: sub a5, a5, a4 2661; RV32-NEXT: xor a5, a1, a5 2662; RV32-NEXT: xor a4, a1, a3 2663; RV32-NEXT: and a4, a4, a5 2664; RV32-NEXT: bltz a4, .LBB38_2 2665; RV32-NEXT: # %bb.1: # %entry 2666; RV32-NEXT: mv a0, a2 2667; RV32-NEXT: mv a1, a3 2668; RV32-NEXT: .LBB38_2: # %entry 2669; RV32-NEXT: ret 2670; 2671; RV64-LABEL: ssubo.select.i64: 2672; RV64: # %bb.0: # %entry 2673; RV64-NEXT: sgtz a2, a1 2674; RV64-NEXT: sub a3, a0, a1 2675; RV64-NEXT: slt a3, a3, a0 2676; RV64-NEXT: bne a2, a3, .LBB38_2 2677; RV64-NEXT: # %bb.1: # %entry 2678; RV64-NEXT: mv a0, a1 2679; RV64-NEXT: .LBB38_2: # %entry 2680; RV64-NEXT: ret 2681; 2682; RV32ZBA-LABEL: ssubo.select.i64: 2683; RV32ZBA: # %bb.0: # %entry 2684; RV32ZBA-NEXT: sltu a4, a0, a2 2685; RV32ZBA-NEXT: sub a5, a1, a3 2686; RV32ZBA-NEXT: sub a5, a5, a4 2687; RV32ZBA-NEXT: xor a5, a1, a5 2688; RV32ZBA-NEXT: xor a4, a1, a3 2689; RV32ZBA-NEXT: and a4, a4, a5 2690; RV32ZBA-NEXT: bltz a4, .LBB38_2 2691; RV32ZBA-NEXT: # %bb.1: # %entry 2692; RV32ZBA-NEXT: mv a0, a2 2693; RV32ZBA-NEXT: mv a1, a3 2694; RV32ZBA-NEXT: .LBB38_2: # %entry 2695; RV32ZBA-NEXT: ret 2696; 2697; RV64ZBA-LABEL: ssubo.select.i64: 2698; RV64ZBA: # %bb.0: # %entry 2699; RV64ZBA-NEXT: sgtz a2, a1 2700; RV64ZBA-NEXT: sub a3, a0, a1 2701; RV64ZBA-NEXT: slt a3, a3, a0 2702; RV64ZBA-NEXT: bne a2, a3, .LBB38_2 2703; RV64ZBA-NEXT: # %bb.1: # %entry 2704; RV64ZBA-NEXT: mv a0, a1 2705; RV64ZBA-NEXT: .LBB38_2: # %entry 2706; RV64ZBA-NEXT: ret 2707; 2708; RV32ZICOND-LABEL: ssubo.select.i64: 2709; RV32ZICOND: # %bb.0: # %entry 2710; RV32ZICOND-NEXT: sltu a4, a0, a2 2711; RV32ZICOND-NEXT: sub a5, a1, a3 2712; RV32ZICOND-NEXT: sub a5, a5, a4 2713; RV32ZICOND-NEXT: xor a4, a1, a3 2714; RV32ZICOND-NEXT: xor a5, a1, a5 2715; RV32ZICOND-NEXT: and a4, a4, a5 2716; RV32ZICOND-NEXT: slti a4, a4, 0 2717; RV32ZICOND-NEXT: czero.nez a2, a2, a4 2718; RV32ZICOND-NEXT: czero.eqz a0, a0, a4 2719; RV32ZICOND-NEXT: czero.nez a3, a3, a4 2720; RV32ZICOND-NEXT: czero.eqz a1, a1, a4 2721; RV32ZICOND-NEXT: or a0, a0, a2 2722; RV32ZICOND-NEXT: or a1, a1, a3 2723; RV32ZICOND-NEXT: ret 2724; 2725; RV64ZICOND-LABEL: ssubo.select.i64: 2726; RV64ZICOND: # %bb.0: # %entry 2727; RV64ZICOND-NEXT: sgtz a2, a1 2728; RV64ZICOND-NEXT: sub a3, a0, a1 2729; RV64ZICOND-NEXT: slt a3, a3, a0 2730; RV64ZICOND-NEXT: xor a2, a2, a3 2731; RV64ZICOND-NEXT: czero.nez a1, a1, a2 2732; RV64ZICOND-NEXT: czero.eqz a0, a0, a2 2733; RV64ZICOND-NEXT: or a0, a0, a1 2734; RV64ZICOND-NEXT: ret 2735entry: 2736 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2) 2737 %obit = extractvalue {i64, i1} %t, 1 2738 %ret = select i1 %obit, i64 %v1, i64 %v2 2739 ret i64 %ret 2740} 2741 2742define i1 @ssub.not.i64(i64 %v1, i64 %v2) { 2743; RV32-LABEL: ssub.not.i64: 2744; RV32: # %bb.0: # %entry 2745; RV32-NEXT: sltu a0, a0, a2 2746; RV32-NEXT: sub a2, a1, a3 2747; RV32-NEXT: sub a2, a2, a0 2748; RV32-NEXT: xor a2, a1, a2 2749; RV32-NEXT: xor a1, a1, a3 2750; RV32-NEXT: and a1, a1, a2 2751; RV32-NEXT: slti a0, a1, 0 2752; RV32-NEXT: xori a0, a0, 1 2753; RV32-NEXT: ret 2754; 2755; RV64-LABEL: ssub.not.i64: 2756; RV64: # %bb.0: # %entry 2757; RV64-NEXT: sgtz a2, a1 2758; RV64-NEXT: sub a1, a0, a1 2759; RV64-NEXT: slt a0, a1, a0 2760; RV64-NEXT: xor a0, a2, a0 2761; RV64-NEXT: xori a0, a0, 1 2762; RV64-NEXT: ret 2763; 2764; RV32ZBA-LABEL: ssub.not.i64: 2765; RV32ZBA: # %bb.0: # %entry 2766; RV32ZBA-NEXT: sltu a0, a0, a2 2767; RV32ZBA-NEXT: sub a2, a1, a3 2768; RV32ZBA-NEXT: sub a2, a2, a0 2769; RV32ZBA-NEXT: xor a2, a1, a2 2770; RV32ZBA-NEXT: xor a1, a1, a3 2771; RV32ZBA-NEXT: and a1, a1, a2 2772; RV32ZBA-NEXT: slti a0, a1, 0 2773; RV32ZBA-NEXT: xori a0, a0, 1 2774; RV32ZBA-NEXT: ret 2775; 2776; RV64ZBA-LABEL: ssub.not.i64: 2777; RV64ZBA: # %bb.0: # %entry 2778; RV64ZBA-NEXT: sgtz a2, a1 2779; RV64ZBA-NEXT: sub a1, a0, a1 2780; RV64ZBA-NEXT: slt a0, a1, a0 2781; RV64ZBA-NEXT: xor a0, a2, a0 2782; RV64ZBA-NEXT: xori a0, a0, 1 2783; RV64ZBA-NEXT: ret 2784; 2785; RV32ZICOND-LABEL: ssub.not.i64: 2786; RV32ZICOND: # %bb.0: # %entry 2787; RV32ZICOND-NEXT: sltu a0, a0, a2 2788; RV32ZICOND-NEXT: sub a2, a1, a3 2789; RV32ZICOND-NEXT: sub a2, a2, a0 2790; RV32ZICOND-NEXT: xor a2, a1, a2 2791; RV32ZICOND-NEXT: xor a1, a1, a3 2792; RV32ZICOND-NEXT: and a1, a1, a2 2793; RV32ZICOND-NEXT: slti a0, a1, 0 2794; RV32ZICOND-NEXT: xori a0, a0, 1 2795; RV32ZICOND-NEXT: ret 2796; 2797; RV64ZICOND-LABEL: ssub.not.i64: 2798; RV64ZICOND: # %bb.0: # %entry 2799; RV64ZICOND-NEXT: sgtz a2, a1 2800; RV64ZICOND-NEXT: sub a1, a0, a1 2801; RV64ZICOND-NEXT: slt a0, a1, a0 2802; RV64ZICOND-NEXT: xor a0, a2, a0 2803; RV64ZICOND-NEXT: xori a0, a0, 1 2804; RV64ZICOND-NEXT: ret 2805entry: 2806 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2) 2807 %obit = extractvalue {i64, i1} %t, 1 2808 %ret = xor i1 %obit, true 2809 ret i1 %ret 2810} 2811 2812define i32 @usubo.select.i32(i32 signext %v1, i32 signext %v2) { 2813; RV32-LABEL: usubo.select.i32: 2814; RV32: # %bb.0: # %entry 2815; RV32-NEXT: sub a2, a0, a1 2816; RV32-NEXT: bltu a0, a2, .LBB40_2 2817; RV32-NEXT: # %bb.1: # %entry 2818; RV32-NEXT: mv a0, a1 2819; RV32-NEXT: .LBB40_2: # %entry 2820; RV32-NEXT: ret 2821; 2822; RV64-LABEL: usubo.select.i32: 2823; RV64: # %bb.0: # %entry 2824; RV64-NEXT: subw a2, a0, a1 2825; RV64-NEXT: bltu a0, a2, .LBB40_2 2826; RV64-NEXT: # %bb.1: # %entry 2827; RV64-NEXT: mv a0, a1 2828; RV64-NEXT: .LBB40_2: # %entry 2829; RV64-NEXT: ret 2830; 2831; RV32ZBA-LABEL: usubo.select.i32: 2832; RV32ZBA: # %bb.0: # %entry 2833; RV32ZBA-NEXT: sub a2, a0, a1 2834; RV32ZBA-NEXT: bltu a0, a2, .LBB40_2 2835; RV32ZBA-NEXT: # %bb.1: # %entry 2836; RV32ZBA-NEXT: mv a0, a1 2837; RV32ZBA-NEXT: .LBB40_2: # %entry 2838; RV32ZBA-NEXT: ret 2839; 2840; RV64ZBA-LABEL: usubo.select.i32: 2841; RV64ZBA: # %bb.0: # %entry 2842; RV64ZBA-NEXT: subw a2, a0, a1 2843; RV64ZBA-NEXT: bltu a0, a2, .LBB40_2 2844; RV64ZBA-NEXT: # %bb.1: # %entry 2845; RV64ZBA-NEXT: mv a0, a1 2846; RV64ZBA-NEXT: .LBB40_2: # %entry 2847; RV64ZBA-NEXT: ret 2848; 2849; RV32ZICOND-LABEL: usubo.select.i32: 2850; RV32ZICOND: # %bb.0: # %entry 2851; RV32ZICOND-NEXT: sub a2, a0, a1 2852; RV32ZICOND-NEXT: sltu a2, a0, a2 2853; RV32ZICOND-NEXT: czero.nez a1, a1, a2 2854; RV32ZICOND-NEXT: czero.eqz a0, a0, a2 2855; RV32ZICOND-NEXT: or a0, a0, a1 2856; RV32ZICOND-NEXT: ret 2857; 2858; RV64ZICOND-LABEL: usubo.select.i32: 2859; RV64ZICOND: # %bb.0: # %entry 2860; RV64ZICOND-NEXT: subw a2, a0, a1 2861; RV64ZICOND-NEXT: sltu a2, a0, a2 2862; RV64ZICOND-NEXT: czero.nez a1, a1, a2 2863; RV64ZICOND-NEXT: czero.eqz a0, a0, a2 2864; RV64ZICOND-NEXT: or a0, a0, a1 2865; RV64ZICOND-NEXT: ret 2866entry: 2867 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2) 2868 %obit = extractvalue {i32, i1} %t, 1 2869 %ret = select i1 %obit, i32 %v1, i32 %v2 2870 ret i32 %ret 2871} 2872 2873define i1 @usubo.not.i32(i32 signext %v1, i32 signext %v2) { 2874; RV32-LABEL: usubo.not.i32: 2875; RV32: # %bb.0: # %entry 2876; RV32-NEXT: sub a1, a0, a1 2877; RV32-NEXT: sltu a0, a0, a1 2878; RV32-NEXT: xori a0, a0, 1 2879; RV32-NEXT: ret 2880; 2881; RV64-LABEL: usubo.not.i32: 2882; RV64: # %bb.0: # %entry 2883; RV64-NEXT: subw a1, a0, a1 2884; RV64-NEXT: sltu a0, a0, a1 2885; RV64-NEXT: xori a0, a0, 1 2886; RV64-NEXT: ret 2887; 2888; RV32ZBA-LABEL: usubo.not.i32: 2889; RV32ZBA: # %bb.0: # %entry 2890; RV32ZBA-NEXT: sub a1, a0, a1 2891; RV32ZBA-NEXT: sltu a0, a0, a1 2892; RV32ZBA-NEXT: xori a0, a0, 1 2893; RV32ZBA-NEXT: ret 2894; 2895; RV64ZBA-LABEL: usubo.not.i32: 2896; RV64ZBA: # %bb.0: # %entry 2897; RV64ZBA-NEXT: subw a1, a0, a1 2898; RV64ZBA-NEXT: sltu a0, a0, a1 2899; RV64ZBA-NEXT: xori a0, a0, 1 2900; RV64ZBA-NEXT: ret 2901; 2902; RV32ZICOND-LABEL: usubo.not.i32: 2903; RV32ZICOND: # %bb.0: # %entry 2904; RV32ZICOND-NEXT: sub a1, a0, a1 2905; RV32ZICOND-NEXT: sltu a0, a0, a1 2906; RV32ZICOND-NEXT: xori a0, a0, 1 2907; RV32ZICOND-NEXT: ret 2908; 2909; RV64ZICOND-LABEL: usubo.not.i32: 2910; RV64ZICOND: # %bb.0: # %entry 2911; RV64ZICOND-NEXT: subw a1, a0, a1 2912; RV64ZICOND-NEXT: sltu a0, a0, a1 2913; RV64ZICOND-NEXT: xori a0, a0, 1 2914; RV64ZICOND-NEXT: ret 2915entry: 2916 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2) 2917 %obit = extractvalue {i32, i1} %t, 1 2918 %ret = xor i1 %obit, true 2919 ret i1 %ret 2920} 2921 2922define i64 @usubo.select.i64(i64 %v1, i64 %v2) { 2923; RV32-LABEL: usubo.select.i64: 2924; RV32: # %bb.0: # %entry 2925; RV32-NEXT: sltu a4, a0, a2 2926; RV32-NEXT: sub a5, a1, a3 2927; RV32-NEXT: sub a4, a5, a4 2928; RV32-NEXT: beq a4, a1, .LBB42_2 2929; RV32-NEXT: # %bb.1: # %entry 2930; RV32-NEXT: sltu a4, a1, a4 2931; RV32-NEXT: beqz a4, .LBB42_3 2932; RV32-NEXT: j .LBB42_4 2933; RV32-NEXT: .LBB42_2: 2934; RV32-NEXT: sub a4, a0, a2 2935; RV32-NEXT: sltu a4, a0, a4 2936; RV32-NEXT: bnez a4, .LBB42_4 2937; RV32-NEXT: .LBB42_3: # %entry 2938; RV32-NEXT: mv a0, a2 2939; RV32-NEXT: mv a1, a3 2940; RV32-NEXT: .LBB42_4: # %entry 2941; RV32-NEXT: ret 2942; 2943; RV64-LABEL: usubo.select.i64: 2944; RV64: # %bb.0: # %entry 2945; RV64-NEXT: sub a2, a0, a1 2946; RV64-NEXT: bltu a0, a2, .LBB42_2 2947; RV64-NEXT: # %bb.1: # %entry 2948; RV64-NEXT: mv a0, a1 2949; RV64-NEXT: .LBB42_2: # %entry 2950; RV64-NEXT: ret 2951; 2952; RV32ZBA-LABEL: usubo.select.i64: 2953; RV32ZBA: # %bb.0: # %entry 2954; RV32ZBA-NEXT: sltu a4, a0, a2 2955; RV32ZBA-NEXT: sub a5, a1, a3 2956; RV32ZBA-NEXT: sub a4, a5, a4 2957; RV32ZBA-NEXT: beq a4, a1, .LBB42_2 2958; RV32ZBA-NEXT: # %bb.1: # %entry 2959; RV32ZBA-NEXT: sltu a4, a1, a4 2960; RV32ZBA-NEXT: beqz a4, .LBB42_3 2961; RV32ZBA-NEXT: j .LBB42_4 2962; RV32ZBA-NEXT: .LBB42_2: 2963; RV32ZBA-NEXT: sub a4, a0, a2 2964; RV32ZBA-NEXT: sltu a4, a0, a4 2965; RV32ZBA-NEXT: bnez a4, .LBB42_4 2966; RV32ZBA-NEXT: .LBB42_3: # %entry 2967; RV32ZBA-NEXT: mv a0, a2 2968; RV32ZBA-NEXT: mv a1, a3 2969; RV32ZBA-NEXT: .LBB42_4: # %entry 2970; RV32ZBA-NEXT: ret 2971; 2972; RV64ZBA-LABEL: usubo.select.i64: 2973; RV64ZBA: # %bb.0: # %entry 2974; RV64ZBA-NEXT: sub a2, a0, a1 2975; RV64ZBA-NEXT: bltu a0, a2, .LBB42_2 2976; RV64ZBA-NEXT: # %bb.1: # %entry 2977; RV64ZBA-NEXT: mv a0, a1 2978; RV64ZBA-NEXT: .LBB42_2: # %entry 2979; RV64ZBA-NEXT: ret 2980; 2981; RV32ZICOND-LABEL: usubo.select.i64: 2982; RV32ZICOND: # %bb.0: # %entry 2983; RV32ZICOND-NEXT: sltu a4, a0, a2 2984; RV32ZICOND-NEXT: sub a5, a1, a3 2985; RV32ZICOND-NEXT: sub a6, a0, a2 2986; RV32ZICOND-NEXT: sub a5, a5, a4 2987; RV32ZICOND-NEXT: sltu a4, a0, a6 2988; RV32ZICOND-NEXT: xor a6, a5, a1 2989; RV32ZICOND-NEXT: sltu a5, a1, a5 2990; RV32ZICOND-NEXT: czero.eqz a5, a5, a6 2991; RV32ZICOND-NEXT: czero.nez a4, a4, a6 2992; RV32ZICOND-NEXT: or a4, a4, a5 2993; RV32ZICOND-NEXT: czero.nez a2, a2, a4 2994; RV32ZICOND-NEXT: czero.eqz a0, a0, a4 2995; RV32ZICOND-NEXT: czero.nez a3, a3, a4 2996; RV32ZICOND-NEXT: czero.eqz a1, a1, a4 2997; RV32ZICOND-NEXT: or a0, a0, a2 2998; RV32ZICOND-NEXT: or a1, a1, a3 2999; RV32ZICOND-NEXT: ret 3000; 3001; RV64ZICOND-LABEL: usubo.select.i64: 3002; RV64ZICOND: # %bb.0: # %entry 3003; RV64ZICOND-NEXT: sub a2, a0, a1 3004; RV64ZICOND-NEXT: sltu a2, a0, a2 3005; RV64ZICOND-NEXT: czero.nez a1, a1, a2 3006; RV64ZICOND-NEXT: czero.eqz a0, a0, a2 3007; RV64ZICOND-NEXT: or a0, a0, a1 3008; RV64ZICOND-NEXT: ret 3009entry: 3010 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2) 3011 %obit = extractvalue {i64, i1} %t, 1 3012 %ret = select i1 %obit, i64 %v1, i64 %v2 3013 ret i64 %ret 3014} 3015 3016define i1 @usubo.not.i64(i64 %v1, i64 %v2) { 3017; RV32-LABEL: usubo.not.i64: 3018; RV32: # %bb.0: # %entry 3019; RV32-NEXT: sltu a4, a0, a2 3020; RV32-NEXT: sub a3, a1, a3 3021; RV32-NEXT: sub a3, a3, a4 3022; RV32-NEXT: beq a3, a1, .LBB43_2 3023; RV32-NEXT: # %bb.1: # %entry 3024; RV32-NEXT: sltu a0, a1, a3 3025; RV32-NEXT: xori a0, a0, 1 3026; RV32-NEXT: ret 3027; RV32-NEXT: .LBB43_2: 3028; RV32-NEXT: sub a1, a0, a2 3029; RV32-NEXT: sltu a0, a0, a1 3030; RV32-NEXT: xori a0, a0, 1 3031; RV32-NEXT: ret 3032; 3033; RV64-LABEL: usubo.not.i64: 3034; RV64: # %bb.0: # %entry 3035; RV64-NEXT: sub a1, a0, a1 3036; RV64-NEXT: sltu a0, a0, a1 3037; RV64-NEXT: xori a0, a0, 1 3038; RV64-NEXT: ret 3039; 3040; RV32ZBA-LABEL: usubo.not.i64: 3041; RV32ZBA: # %bb.0: # %entry 3042; RV32ZBA-NEXT: sltu a4, a0, a2 3043; RV32ZBA-NEXT: sub a3, a1, a3 3044; RV32ZBA-NEXT: sub a3, a3, a4 3045; RV32ZBA-NEXT: beq a3, a1, .LBB43_2 3046; RV32ZBA-NEXT: # %bb.1: # %entry 3047; RV32ZBA-NEXT: sltu a0, a1, a3 3048; RV32ZBA-NEXT: xori a0, a0, 1 3049; RV32ZBA-NEXT: ret 3050; RV32ZBA-NEXT: .LBB43_2: 3051; RV32ZBA-NEXT: sub a1, a0, a2 3052; RV32ZBA-NEXT: sltu a0, a0, a1 3053; RV32ZBA-NEXT: xori a0, a0, 1 3054; RV32ZBA-NEXT: ret 3055; 3056; RV64ZBA-LABEL: usubo.not.i64: 3057; RV64ZBA: # %bb.0: # %entry 3058; RV64ZBA-NEXT: sub a1, a0, a1 3059; RV64ZBA-NEXT: sltu a0, a0, a1 3060; RV64ZBA-NEXT: xori a0, a0, 1 3061; RV64ZBA-NEXT: ret 3062; 3063; RV32ZICOND-LABEL: usubo.not.i64: 3064; RV32ZICOND: # %bb.0: # %entry 3065; RV32ZICOND-NEXT: sltu a4, a0, a2 3066; RV32ZICOND-NEXT: sub a3, a1, a3 3067; RV32ZICOND-NEXT: sub a2, a0, a2 3068; RV32ZICOND-NEXT: sub a3, a3, a4 3069; RV32ZICOND-NEXT: sltu a0, a0, a2 3070; RV32ZICOND-NEXT: xor a2, a3, a1 3071; RV32ZICOND-NEXT: sltu a1, a1, a3 3072; RV32ZICOND-NEXT: czero.eqz a1, a1, a2 3073; RV32ZICOND-NEXT: czero.nez a0, a0, a2 3074; RV32ZICOND-NEXT: or a0, a0, a1 3075; RV32ZICOND-NEXT: xori a0, a0, 1 3076; RV32ZICOND-NEXT: ret 3077; 3078; RV64ZICOND-LABEL: usubo.not.i64: 3079; RV64ZICOND: # %bb.0: # %entry 3080; RV64ZICOND-NEXT: sub a1, a0, a1 3081; RV64ZICOND-NEXT: sltu a0, a0, a1 3082; RV64ZICOND-NEXT: xori a0, a0, 1 3083; RV64ZICOND-NEXT: ret 3084entry: 3085 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2) 3086 %obit = extractvalue {i64, i1} %t, 1 3087 %ret = xor i1 %obit, true 3088 ret i1 %ret 3089} 3090 3091define i32 @smulo.select.i32(i32 signext %v1, i32 signext %v2) { 3092; RV32-LABEL: smulo.select.i32: 3093; RV32: # %bb.0: # %entry 3094; RV32-NEXT: mulh a2, a0, a1 3095; RV32-NEXT: mul a3, a0, a1 3096; RV32-NEXT: srai a3, a3, 31 3097; RV32-NEXT: bne a2, a3, .LBB44_2 3098; RV32-NEXT: # %bb.1: # %entry 3099; RV32-NEXT: mv a0, a1 3100; RV32-NEXT: .LBB44_2: # %entry 3101; RV32-NEXT: ret 3102; 3103; RV64-LABEL: smulo.select.i32: 3104; RV64: # %bb.0: # %entry 3105; RV64-NEXT: mul a2, a0, a1 3106; RV64-NEXT: mulw a3, a0, a1 3107; RV64-NEXT: bne a3, a2, .LBB44_2 3108; RV64-NEXT: # %bb.1: # %entry 3109; RV64-NEXT: mv a0, a1 3110; RV64-NEXT: .LBB44_2: # %entry 3111; RV64-NEXT: ret 3112; 3113; RV32ZBA-LABEL: smulo.select.i32: 3114; RV32ZBA: # %bb.0: # %entry 3115; RV32ZBA-NEXT: mulh a2, a0, a1 3116; RV32ZBA-NEXT: mul a3, a0, a1 3117; RV32ZBA-NEXT: srai a3, a3, 31 3118; RV32ZBA-NEXT: bne a2, a3, .LBB44_2 3119; RV32ZBA-NEXT: # %bb.1: # %entry 3120; RV32ZBA-NEXT: mv a0, a1 3121; RV32ZBA-NEXT: .LBB44_2: # %entry 3122; RV32ZBA-NEXT: ret 3123; 3124; RV64ZBA-LABEL: smulo.select.i32: 3125; RV64ZBA: # %bb.0: # %entry 3126; RV64ZBA-NEXT: mul a2, a0, a1 3127; RV64ZBA-NEXT: mulw a3, a0, a1 3128; RV64ZBA-NEXT: bne a3, a2, .LBB44_2 3129; RV64ZBA-NEXT: # %bb.1: # %entry 3130; RV64ZBA-NEXT: mv a0, a1 3131; RV64ZBA-NEXT: .LBB44_2: # %entry 3132; RV64ZBA-NEXT: ret 3133; 3134; RV32ZICOND-LABEL: smulo.select.i32: 3135; RV32ZICOND: # %bb.0: # %entry 3136; RV32ZICOND-NEXT: mulh a2, a0, a1 3137; RV32ZICOND-NEXT: mul a3, a0, a1 3138; RV32ZICOND-NEXT: srai a3, a3, 31 3139; RV32ZICOND-NEXT: xor a2, a2, a3 3140; RV32ZICOND-NEXT: czero.nez a1, a1, a2 3141; RV32ZICOND-NEXT: czero.eqz a0, a0, a2 3142; RV32ZICOND-NEXT: or a0, a0, a1 3143; RV32ZICOND-NEXT: ret 3144; 3145; RV64ZICOND-LABEL: smulo.select.i32: 3146; RV64ZICOND: # %bb.0: # %entry 3147; RV64ZICOND-NEXT: mul a2, a0, a1 3148; RV64ZICOND-NEXT: mulw a3, a0, a1 3149; RV64ZICOND-NEXT: xor a2, a3, a2 3150; RV64ZICOND-NEXT: czero.nez a1, a1, a2 3151; RV64ZICOND-NEXT: czero.eqz a0, a0, a2 3152; RV64ZICOND-NEXT: or a0, a0, a1 3153; RV64ZICOND-NEXT: ret 3154entry: 3155 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2) 3156 %obit = extractvalue {i32, i1} %t, 1 3157 %ret = select i1 %obit, i32 %v1, i32 %v2 3158 ret i32 %ret 3159} 3160 3161define i1 @smulo.not.i32(i32 signext %v1, i32 signext %v2) { 3162; RV32-LABEL: smulo.not.i32: 3163; RV32: # %bb.0: # %entry 3164; RV32-NEXT: mulh a2, a0, a1 3165; RV32-NEXT: mul a0, a0, a1 3166; RV32-NEXT: srai a0, a0, 31 3167; RV32-NEXT: xor a0, a2, a0 3168; RV32-NEXT: seqz a0, a0 3169; RV32-NEXT: ret 3170; 3171; RV64-LABEL: smulo.not.i32: 3172; RV64: # %bb.0: # %entry 3173; RV64-NEXT: mul a2, a0, a1 3174; RV64-NEXT: mulw a0, a0, a1 3175; RV64-NEXT: xor a0, a0, a2 3176; RV64-NEXT: seqz a0, a0 3177; RV64-NEXT: ret 3178; 3179; RV32ZBA-LABEL: smulo.not.i32: 3180; RV32ZBA: # %bb.0: # %entry 3181; RV32ZBA-NEXT: mulh a2, a0, a1 3182; RV32ZBA-NEXT: mul a0, a0, a1 3183; RV32ZBA-NEXT: srai a0, a0, 31 3184; RV32ZBA-NEXT: xor a0, a2, a0 3185; RV32ZBA-NEXT: seqz a0, a0 3186; RV32ZBA-NEXT: ret 3187; 3188; RV64ZBA-LABEL: smulo.not.i32: 3189; RV64ZBA: # %bb.0: # %entry 3190; RV64ZBA-NEXT: mul a2, a0, a1 3191; RV64ZBA-NEXT: mulw a0, a0, a1 3192; RV64ZBA-NEXT: xor a0, a0, a2 3193; RV64ZBA-NEXT: seqz a0, a0 3194; RV64ZBA-NEXT: ret 3195; 3196; RV32ZICOND-LABEL: smulo.not.i32: 3197; RV32ZICOND: # %bb.0: # %entry 3198; RV32ZICOND-NEXT: mulh a2, a0, a1 3199; RV32ZICOND-NEXT: mul a0, a0, a1 3200; RV32ZICOND-NEXT: srai a0, a0, 31 3201; RV32ZICOND-NEXT: xor a0, a2, a0 3202; RV32ZICOND-NEXT: seqz a0, a0 3203; RV32ZICOND-NEXT: ret 3204; 3205; RV64ZICOND-LABEL: smulo.not.i32: 3206; RV64ZICOND: # %bb.0: # %entry 3207; RV64ZICOND-NEXT: mul a2, a0, a1 3208; RV64ZICOND-NEXT: mulw a0, a0, a1 3209; RV64ZICOND-NEXT: xor a0, a0, a2 3210; RV64ZICOND-NEXT: seqz a0, a0 3211; RV64ZICOND-NEXT: ret 3212entry: 3213 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2) 3214 %obit = extractvalue {i32, i1} %t, 1 3215 %ret = xor i1 %obit, true 3216 ret i1 %ret 3217} 3218 3219define i64 @smulo.select.i64(i64 %v1, i64 %v2) { 3220; RV32-LABEL: smulo.select.i64: 3221; RV32: # %bb.0: # %entry 3222; RV32-NEXT: mulhu a4, a0, a2 3223; RV32-NEXT: mul a5, a1, a2 3224; RV32-NEXT: mulhsu a6, a1, a2 3225; RV32-NEXT: mul a7, a3, a0 3226; RV32-NEXT: mulhsu t0, a3, a0 3227; RV32-NEXT: add a4, a5, a4 3228; RV32-NEXT: sltu a5, a4, a5 3229; RV32-NEXT: add a4, a7, a4 3230; RV32-NEXT: add a5, a6, a5 3231; RV32-NEXT: sltu a6, a4, a7 3232; RV32-NEXT: add a6, t0, a6 3233; RV32-NEXT: srai a7, a5, 31 3234; RV32-NEXT: srai t0, a6, 31 3235; RV32-NEXT: add a7, a7, t0 3236; RV32-NEXT: mulh t0, a1, a3 3237; RV32-NEXT: add a6, a5, a6 3238; RV32-NEXT: sltu a5, a6, a5 3239; RV32-NEXT: add a5, a7, a5 3240; RV32-NEXT: mul a7, a1, a3 3241; RV32-NEXT: srai a4, a4, 31 3242; RV32-NEXT: add a6, a7, a6 3243; RV32-NEXT: sltu a7, a6, a7 3244; RV32-NEXT: add a5, t0, a5 3245; RV32-NEXT: add a5, a5, a7 3246; RV32-NEXT: xor a5, a5, a4 3247; RV32-NEXT: xor a4, a6, a4 3248; RV32-NEXT: or a4, a4, a5 3249; RV32-NEXT: bnez a4, .LBB46_2 3250; RV32-NEXT: # %bb.1: # %entry 3251; RV32-NEXT: mv a0, a2 3252; RV32-NEXT: mv a1, a3 3253; RV32-NEXT: .LBB46_2: # %entry 3254; RV32-NEXT: ret 3255; 3256; RV64-LABEL: smulo.select.i64: 3257; RV64: # %bb.0: # %entry 3258; RV64-NEXT: mulh a2, a0, a1 3259; RV64-NEXT: mul a3, a0, a1 3260; RV64-NEXT: srai a3, a3, 63 3261; RV64-NEXT: bne a2, a3, .LBB46_2 3262; RV64-NEXT: # %bb.1: # %entry 3263; RV64-NEXT: mv a0, a1 3264; RV64-NEXT: .LBB46_2: # %entry 3265; RV64-NEXT: ret 3266; 3267; RV32ZBA-LABEL: smulo.select.i64: 3268; RV32ZBA: # %bb.0: # %entry 3269; RV32ZBA-NEXT: mulhu a4, a0, a2 3270; RV32ZBA-NEXT: mul a5, a1, a2 3271; RV32ZBA-NEXT: mulhsu a6, a1, a2 3272; RV32ZBA-NEXT: mul a7, a3, a0 3273; RV32ZBA-NEXT: mulhsu t0, a3, a0 3274; RV32ZBA-NEXT: add a4, a5, a4 3275; RV32ZBA-NEXT: sltu a5, a4, a5 3276; RV32ZBA-NEXT: add a4, a7, a4 3277; RV32ZBA-NEXT: add a5, a6, a5 3278; RV32ZBA-NEXT: sltu a6, a4, a7 3279; RV32ZBA-NEXT: add a6, t0, a6 3280; RV32ZBA-NEXT: srai a7, a5, 31 3281; RV32ZBA-NEXT: srai t0, a6, 31 3282; RV32ZBA-NEXT: add a7, a7, t0 3283; RV32ZBA-NEXT: mulh t0, a1, a3 3284; RV32ZBA-NEXT: add a6, a5, a6 3285; RV32ZBA-NEXT: sltu a5, a6, a5 3286; RV32ZBA-NEXT: add a5, a7, a5 3287; RV32ZBA-NEXT: mul a7, a1, a3 3288; RV32ZBA-NEXT: srai a4, a4, 31 3289; RV32ZBA-NEXT: add a6, a7, a6 3290; RV32ZBA-NEXT: sltu a7, a6, a7 3291; RV32ZBA-NEXT: add a5, t0, a5 3292; RV32ZBA-NEXT: add a5, a5, a7 3293; RV32ZBA-NEXT: xor a5, a5, a4 3294; RV32ZBA-NEXT: xor a4, a6, a4 3295; RV32ZBA-NEXT: or a4, a4, a5 3296; RV32ZBA-NEXT: bnez a4, .LBB46_2 3297; RV32ZBA-NEXT: # %bb.1: # %entry 3298; RV32ZBA-NEXT: mv a0, a2 3299; RV32ZBA-NEXT: mv a1, a3 3300; RV32ZBA-NEXT: .LBB46_2: # %entry 3301; RV32ZBA-NEXT: ret 3302; 3303; RV64ZBA-LABEL: smulo.select.i64: 3304; RV64ZBA: # %bb.0: # %entry 3305; RV64ZBA-NEXT: mulh a2, a0, a1 3306; RV64ZBA-NEXT: mul a3, a0, a1 3307; RV64ZBA-NEXT: srai a3, a3, 63 3308; RV64ZBA-NEXT: bne a2, a3, .LBB46_2 3309; RV64ZBA-NEXT: # %bb.1: # %entry 3310; RV64ZBA-NEXT: mv a0, a1 3311; RV64ZBA-NEXT: .LBB46_2: # %entry 3312; RV64ZBA-NEXT: ret 3313; 3314; RV32ZICOND-LABEL: smulo.select.i64: 3315; RV32ZICOND: # %bb.0: # %entry 3316; RV32ZICOND-NEXT: mulhu a4, a0, a2 3317; RV32ZICOND-NEXT: mul a5, a1, a2 3318; RV32ZICOND-NEXT: mulhsu a6, a1, a2 3319; RV32ZICOND-NEXT: mul a7, a3, a0 3320; RV32ZICOND-NEXT: mulhsu t0, a3, a0 3321; RV32ZICOND-NEXT: add a4, a5, a4 3322; RV32ZICOND-NEXT: sltu a5, a4, a5 3323; RV32ZICOND-NEXT: add a4, a7, a4 3324; RV32ZICOND-NEXT: add a5, a6, a5 3325; RV32ZICOND-NEXT: sltu a6, a4, a7 3326; RV32ZICOND-NEXT: add a6, t0, a6 3327; RV32ZICOND-NEXT: srai a7, a5, 31 3328; RV32ZICOND-NEXT: srai t0, a6, 31 3329; RV32ZICOND-NEXT: add a7, a7, t0 3330; RV32ZICOND-NEXT: mulh t0, a1, a3 3331; RV32ZICOND-NEXT: add a6, a5, a6 3332; RV32ZICOND-NEXT: sltu a5, a6, a5 3333; RV32ZICOND-NEXT: add a5, a7, a5 3334; RV32ZICOND-NEXT: mul a7, a1, a3 3335; RV32ZICOND-NEXT: srai a4, a4, 31 3336; RV32ZICOND-NEXT: add a6, a7, a6 3337; RV32ZICOND-NEXT: sltu a7, a6, a7 3338; RV32ZICOND-NEXT: xor a6, a6, a4 3339; RV32ZICOND-NEXT: add a5, t0, a5 3340; RV32ZICOND-NEXT: add a5, a5, a7 3341; RV32ZICOND-NEXT: xor a4, a5, a4 3342; RV32ZICOND-NEXT: or a4, a6, a4 3343; RV32ZICOND-NEXT: czero.nez a2, a2, a4 3344; RV32ZICOND-NEXT: czero.eqz a0, a0, a4 3345; RV32ZICOND-NEXT: czero.nez a3, a3, a4 3346; RV32ZICOND-NEXT: czero.eqz a1, a1, a4 3347; RV32ZICOND-NEXT: or a0, a0, a2 3348; RV32ZICOND-NEXT: or a1, a1, a3 3349; RV32ZICOND-NEXT: ret 3350; 3351; RV64ZICOND-LABEL: smulo.select.i64: 3352; RV64ZICOND: # %bb.0: # %entry 3353; RV64ZICOND-NEXT: mulh a2, a0, a1 3354; RV64ZICOND-NEXT: mul a3, a0, a1 3355; RV64ZICOND-NEXT: srai a3, a3, 63 3356; RV64ZICOND-NEXT: xor a2, a2, a3 3357; RV64ZICOND-NEXT: czero.nez a1, a1, a2 3358; RV64ZICOND-NEXT: czero.eqz a0, a0, a2 3359; RV64ZICOND-NEXT: or a0, a0, a1 3360; RV64ZICOND-NEXT: ret 3361entry: 3362 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2) 3363 %obit = extractvalue {i64, i1} %t, 1 3364 %ret = select i1 %obit, i64 %v1, i64 %v2 3365 ret i64 %ret 3366} 3367 3368define i1 @smulo.not.i64(i64 %v1, i64 %v2) { 3369; RV32-LABEL: smulo.not.i64: 3370; RV32: # %bb.0: # %entry 3371; RV32-NEXT: mulhu a4, a0, a2 3372; RV32-NEXT: mul a5, a1, a2 3373; RV32-NEXT: mulhsu a2, a1, a2 3374; RV32-NEXT: mul a6, a3, a0 3375; RV32-NEXT: mulhsu a0, a3, a0 3376; RV32-NEXT: mulh a7, a1, a3 3377; RV32-NEXT: mul a1, a1, a3 3378; RV32-NEXT: add a4, a5, a4 3379; RV32-NEXT: sltu a3, a4, a5 3380; RV32-NEXT: add a4, a6, a4 3381; RV32-NEXT: add a2, a2, a3 3382; RV32-NEXT: sltu a3, a4, a6 3383; RV32-NEXT: srai a4, a4, 31 3384; RV32-NEXT: add a0, a0, a3 3385; RV32-NEXT: srai a3, a2, 31 3386; RV32-NEXT: add a5, a2, a0 3387; RV32-NEXT: srai a0, a0, 31 3388; RV32-NEXT: sltu a2, a5, a2 3389; RV32-NEXT: add a0, a3, a0 3390; RV32-NEXT: add a5, a1, a5 3391; RV32-NEXT: add a0, a0, a2 3392; RV32-NEXT: sltu a1, a5, a1 3393; RV32-NEXT: add a0, a7, a0 3394; RV32-NEXT: add a0, a0, a1 3395; RV32-NEXT: xor a0, a0, a4 3396; RV32-NEXT: xor a4, a5, a4 3397; RV32-NEXT: or a0, a4, a0 3398; RV32-NEXT: seqz a0, a0 3399; RV32-NEXT: ret 3400; 3401; RV64-LABEL: smulo.not.i64: 3402; RV64: # %bb.0: # %entry 3403; RV64-NEXT: mulh a2, a0, a1 3404; RV64-NEXT: mul a0, a0, a1 3405; RV64-NEXT: srai a0, a0, 63 3406; RV64-NEXT: xor a0, a2, a0 3407; RV64-NEXT: seqz a0, a0 3408; RV64-NEXT: ret 3409; 3410; RV32ZBA-LABEL: smulo.not.i64: 3411; RV32ZBA: # %bb.0: # %entry 3412; RV32ZBA-NEXT: mulhu a4, a0, a2 3413; RV32ZBA-NEXT: mul a5, a1, a2 3414; RV32ZBA-NEXT: mulhsu a2, a1, a2 3415; RV32ZBA-NEXT: mul a6, a3, a0 3416; RV32ZBA-NEXT: mulhsu a0, a3, a0 3417; RV32ZBA-NEXT: mulh a7, a1, a3 3418; RV32ZBA-NEXT: mul a1, a1, a3 3419; RV32ZBA-NEXT: add a4, a5, a4 3420; RV32ZBA-NEXT: sltu a3, a4, a5 3421; RV32ZBA-NEXT: add a4, a6, a4 3422; RV32ZBA-NEXT: add a2, a2, a3 3423; RV32ZBA-NEXT: sltu a3, a4, a6 3424; RV32ZBA-NEXT: srai a4, a4, 31 3425; RV32ZBA-NEXT: add a0, a0, a3 3426; RV32ZBA-NEXT: srai a3, a2, 31 3427; RV32ZBA-NEXT: add a5, a2, a0 3428; RV32ZBA-NEXT: srai a0, a0, 31 3429; RV32ZBA-NEXT: sltu a2, a5, a2 3430; RV32ZBA-NEXT: add a0, a3, a0 3431; RV32ZBA-NEXT: add a5, a1, a5 3432; RV32ZBA-NEXT: add a0, a0, a2 3433; RV32ZBA-NEXT: sltu a1, a5, a1 3434; RV32ZBA-NEXT: add a0, a7, a0 3435; RV32ZBA-NEXT: add a0, a0, a1 3436; RV32ZBA-NEXT: xor a0, a0, a4 3437; RV32ZBA-NEXT: xor a4, a5, a4 3438; RV32ZBA-NEXT: or a0, a4, a0 3439; RV32ZBA-NEXT: seqz a0, a0 3440; RV32ZBA-NEXT: ret 3441; 3442; RV64ZBA-LABEL: smulo.not.i64: 3443; RV64ZBA: # %bb.0: # %entry 3444; RV64ZBA-NEXT: mulh a2, a0, a1 3445; RV64ZBA-NEXT: mul a0, a0, a1 3446; RV64ZBA-NEXT: srai a0, a0, 63 3447; RV64ZBA-NEXT: xor a0, a2, a0 3448; RV64ZBA-NEXT: seqz a0, a0 3449; RV64ZBA-NEXT: ret 3450; 3451; RV32ZICOND-LABEL: smulo.not.i64: 3452; RV32ZICOND: # %bb.0: # %entry 3453; RV32ZICOND-NEXT: mulhu a4, a0, a2 3454; RV32ZICOND-NEXT: mul a5, a1, a2 3455; RV32ZICOND-NEXT: mulhsu a2, a1, a2 3456; RV32ZICOND-NEXT: mul a6, a3, a0 3457; RV32ZICOND-NEXT: mulhsu a0, a3, a0 3458; RV32ZICOND-NEXT: mulh a7, a1, a3 3459; RV32ZICOND-NEXT: mul a1, a1, a3 3460; RV32ZICOND-NEXT: add a4, a5, a4 3461; RV32ZICOND-NEXT: sltu a3, a4, a5 3462; RV32ZICOND-NEXT: add a4, a6, a4 3463; RV32ZICOND-NEXT: add a2, a2, a3 3464; RV32ZICOND-NEXT: sltu a3, a4, a6 3465; RV32ZICOND-NEXT: srai a4, a4, 31 3466; RV32ZICOND-NEXT: add a0, a0, a3 3467; RV32ZICOND-NEXT: srai a3, a2, 31 3468; RV32ZICOND-NEXT: add a5, a2, a0 3469; RV32ZICOND-NEXT: srai a0, a0, 31 3470; RV32ZICOND-NEXT: sltu a2, a5, a2 3471; RV32ZICOND-NEXT: add a0, a3, a0 3472; RV32ZICOND-NEXT: add a5, a1, a5 3473; RV32ZICOND-NEXT: add a0, a0, a2 3474; RV32ZICOND-NEXT: sltu a1, a5, a1 3475; RV32ZICOND-NEXT: add a0, a7, a0 3476; RV32ZICOND-NEXT: add a0, a0, a1 3477; RV32ZICOND-NEXT: xor a0, a0, a4 3478; RV32ZICOND-NEXT: xor a4, a5, a4 3479; RV32ZICOND-NEXT: or a0, a4, a0 3480; RV32ZICOND-NEXT: seqz a0, a0 3481; RV32ZICOND-NEXT: ret 3482; 3483; RV64ZICOND-LABEL: smulo.not.i64: 3484; RV64ZICOND: # %bb.0: # %entry 3485; RV64ZICOND-NEXT: mulh a2, a0, a1 3486; RV64ZICOND-NEXT: mul a0, a0, a1 3487; RV64ZICOND-NEXT: srai a0, a0, 63 3488; RV64ZICOND-NEXT: xor a0, a2, a0 3489; RV64ZICOND-NEXT: seqz a0, a0 3490; RV64ZICOND-NEXT: ret 3491entry: 3492 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2) 3493 %obit = extractvalue {i64, i1} %t, 1 3494 %ret = xor i1 %obit, true 3495 ret i1 %ret 3496} 3497 3498define i32 @umulo.select.i32(i32 signext %v1, i32 signext %v2) { 3499; RV32-LABEL: umulo.select.i32: 3500; RV32: # %bb.0: # %entry 3501; RV32-NEXT: mulhu a2, a0, a1 3502; RV32-NEXT: bnez a2, .LBB48_2 3503; RV32-NEXT: # %bb.1: # %entry 3504; RV32-NEXT: mv a0, a1 3505; RV32-NEXT: .LBB48_2: # %entry 3506; RV32-NEXT: ret 3507; 3508; RV64-LABEL: umulo.select.i32: 3509; RV64: # %bb.0: # %entry 3510; RV64-NEXT: slli a2, a1, 32 3511; RV64-NEXT: slli a3, a0, 32 3512; RV64-NEXT: mulhu a2, a3, a2 3513; RV64-NEXT: srli a2, a2, 32 3514; RV64-NEXT: bnez a2, .LBB48_2 3515; RV64-NEXT: # %bb.1: # %entry 3516; RV64-NEXT: mv a0, a1 3517; RV64-NEXT: .LBB48_2: # %entry 3518; RV64-NEXT: ret 3519; 3520; RV32ZBA-LABEL: umulo.select.i32: 3521; RV32ZBA: # %bb.0: # %entry 3522; RV32ZBA-NEXT: mulhu a2, a0, a1 3523; RV32ZBA-NEXT: bnez a2, .LBB48_2 3524; RV32ZBA-NEXT: # %bb.1: # %entry 3525; RV32ZBA-NEXT: mv a0, a1 3526; RV32ZBA-NEXT: .LBB48_2: # %entry 3527; RV32ZBA-NEXT: ret 3528; 3529; RV64ZBA-LABEL: umulo.select.i32: 3530; RV64ZBA: # %bb.0: # %entry 3531; RV64ZBA-NEXT: zext.w a2, a1 3532; RV64ZBA-NEXT: zext.w a3, a0 3533; RV64ZBA-NEXT: mul a2, a3, a2 3534; RV64ZBA-NEXT: srli a2, a2, 32 3535; RV64ZBA-NEXT: bnez a2, .LBB48_2 3536; RV64ZBA-NEXT: # %bb.1: # %entry 3537; RV64ZBA-NEXT: mv a0, a1 3538; RV64ZBA-NEXT: .LBB48_2: # %entry 3539; RV64ZBA-NEXT: ret 3540; 3541; RV32ZICOND-LABEL: umulo.select.i32: 3542; RV32ZICOND: # %bb.0: # %entry 3543; RV32ZICOND-NEXT: mulhu a2, a0, a1 3544; RV32ZICOND-NEXT: czero.nez a1, a1, a2 3545; RV32ZICOND-NEXT: czero.eqz a0, a0, a2 3546; RV32ZICOND-NEXT: or a0, a0, a1 3547; RV32ZICOND-NEXT: ret 3548; 3549; RV64ZICOND-LABEL: umulo.select.i32: 3550; RV64ZICOND: # %bb.0: # %entry 3551; RV64ZICOND-NEXT: slli a2, a1, 32 3552; RV64ZICOND-NEXT: slli a3, a0, 32 3553; RV64ZICOND-NEXT: mulhu a2, a3, a2 3554; RV64ZICOND-NEXT: srli a2, a2, 32 3555; RV64ZICOND-NEXT: czero.nez a1, a1, a2 3556; RV64ZICOND-NEXT: czero.eqz a0, a0, a2 3557; RV64ZICOND-NEXT: or a0, a0, a1 3558; RV64ZICOND-NEXT: ret 3559entry: 3560 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2) 3561 %obit = extractvalue {i32, i1} %t, 1 3562 %ret = select i1 %obit, i32 %v1, i32 %v2 3563 ret i32 %ret 3564} 3565 3566define i1 @umulo.not.i32(i32 signext %v1, i32 signext %v2) { 3567; RV32-LABEL: umulo.not.i32: 3568; RV32: # %bb.0: # %entry 3569; RV32-NEXT: mulhu a0, a0, a1 3570; RV32-NEXT: seqz a0, a0 3571; RV32-NEXT: ret 3572; 3573; RV64-LABEL: umulo.not.i32: 3574; RV64: # %bb.0: # %entry 3575; RV64-NEXT: slli a1, a1, 32 3576; RV64-NEXT: slli a0, a0, 32 3577; RV64-NEXT: mulhu a0, a0, a1 3578; RV64-NEXT: srli a0, a0, 32 3579; RV64-NEXT: seqz a0, a0 3580; RV64-NEXT: ret 3581; 3582; RV32ZBA-LABEL: umulo.not.i32: 3583; RV32ZBA: # %bb.0: # %entry 3584; RV32ZBA-NEXT: mulhu a0, a0, a1 3585; RV32ZBA-NEXT: seqz a0, a0 3586; RV32ZBA-NEXT: ret 3587; 3588; RV64ZBA-LABEL: umulo.not.i32: 3589; RV64ZBA: # %bb.0: # %entry 3590; RV64ZBA-NEXT: zext.w a1, a1 3591; RV64ZBA-NEXT: zext.w a0, a0 3592; RV64ZBA-NEXT: mul a0, a0, a1 3593; RV64ZBA-NEXT: srli a0, a0, 32 3594; RV64ZBA-NEXT: seqz a0, a0 3595; RV64ZBA-NEXT: ret 3596; 3597; RV32ZICOND-LABEL: umulo.not.i32: 3598; RV32ZICOND: # %bb.0: # %entry 3599; RV32ZICOND-NEXT: mulhu a0, a0, a1 3600; RV32ZICOND-NEXT: seqz a0, a0 3601; RV32ZICOND-NEXT: ret 3602; 3603; RV64ZICOND-LABEL: umulo.not.i32: 3604; RV64ZICOND: # %bb.0: # %entry 3605; RV64ZICOND-NEXT: slli a1, a1, 32 3606; RV64ZICOND-NEXT: slli a0, a0, 32 3607; RV64ZICOND-NEXT: mulhu a0, a0, a1 3608; RV64ZICOND-NEXT: srli a0, a0, 32 3609; RV64ZICOND-NEXT: seqz a0, a0 3610; RV64ZICOND-NEXT: ret 3611entry: 3612 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2) 3613 %obit = extractvalue {i32, i1} %t, 1 3614 %ret = xor i1 %obit, true 3615 ret i1 %ret 3616} 3617 3618define i64 @umulo.select.i64(i64 %v1, i64 %v2) { 3619; RV32-LABEL: umulo.select.i64: 3620; RV32: # %bb.0: # %entry 3621; RV32-NEXT: mul a4, a3, a0 3622; RV32-NEXT: mul a5, a1, a2 3623; RV32-NEXT: snez a6, a3 3624; RV32-NEXT: add a4, a5, a4 3625; RV32-NEXT: snez a5, a1 3626; RV32-NEXT: and a5, a5, a6 3627; RV32-NEXT: mulhu a6, a1, a2 3628; RV32-NEXT: snez a6, a6 3629; RV32-NEXT: or a5, a5, a6 3630; RV32-NEXT: mulhu a6, a0, a2 3631; RV32-NEXT: add a4, a6, a4 3632; RV32-NEXT: sltu a4, a4, a6 3633; RV32-NEXT: mulhu a6, a3, a0 3634; RV32-NEXT: snez a6, a6 3635; RV32-NEXT: or a5, a5, a6 3636; RV32-NEXT: or a4, a5, a4 3637; RV32-NEXT: bnez a4, .LBB50_2 3638; RV32-NEXT: # %bb.1: # %entry 3639; RV32-NEXT: mv a0, a2 3640; RV32-NEXT: mv a1, a3 3641; RV32-NEXT: .LBB50_2: # %entry 3642; RV32-NEXT: ret 3643; 3644; RV64-LABEL: umulo.select.i64: 3645; RV64: # %bb.0: # %entry 3646; RV64-NEXT: mulhu a2, a0, a1 3647; RV64-NEXT: bnez a2, .LBB50_2 3648; RV64-NEXT: # %bb.1: # %entry 3649; RV64-NEXT: mv a0, a1 3650; RV64-NEXT: .LBB50_2: # %entry 3651; RV64-NEXT: ret 3652; 3653; RV32ZBA-LABEL: umulo.select.i64: 3654; RV32ZBA: # %bb.0: # %entry 3655; RV32ZBA-NEXT: mul a4, a3, a0 3656; RV32ZBA-NEXT: mul a5, a1, a2 3657; RV32ZBA-NEXT: snez a6, a3 3658; RV32ZBA-NEXT: add a4, a5, a4 3659; RV32ZBA-NEXT: snez a5, a1 3660; RV32ZBA-NEXT: and a5, a5, a6 3661; RV32ZBA-NEXT: mulhu a6, a1, a2 3662; RV32ZBA-NEXT: snez a6, a6 3663; RV32ZBA-NEXT: or a5, a5, a6 3664; RV32ZBA-NEXT: mulhu a6, a0, a2 3665; RV32ZBA-NEXT: add a4, a6, a4 3666; RV32ZBA-NEXT: sltu a4, a4, a6 3667; RV32ZBA-NEXT: mulhu a6, a3, a0 3668; RV32ZBA-NEXT: snez a6, a6 3669; RV32ZBA-NEXT: or a5, a5, a6 3670; RV32ZBA-NEXT: or a4, a5, a4 3671; RV32ZBA-NEXT: bnez a4, .LBB50_2 3672; RV32ZBA-NEXT: # %bb.1: # %entry 3673; RV32ZBA-NEXT: mv a0, a2 3674; RV32ZBA-NEXT: mv a1, a3 3675; RV32ZBA-NEXT: .LBB50_2: # %entry 3676; RV32ZBA-NEXT: ret 3677; 3678; RV64ZBA-LABEL: umulo.select.i64: 3679; RV64ZBA: # %bb.0: # %entry 3680; RV64ZBA-NEXT: mulhu a2, a0, a1 3681; RV64ZBA-NEXT: bnez a2, .LBB50_2 3682; RV64ZBA-NEXT: # %bb.1: # %entry 3683; RV64ZBA-NEXT: mv a0, a1 3684; RV64ZBA-NEXT: .LBB50_2: # %entry 3685; RV64ZBA-NEXT: ret 3686; 3687; RV32ZICOND-LABEL: umulo.select.i64: 3688; RV32ZICOND: # %bb.0: # %entry 3689; RV32ZICOND-NEXT: mul a4, a3, a0 3690; RV32ZICOND-NEXT: mul a5, a1, a2 3691; RV32ZICOND-NEXT: snez a6, a3 3692; RV32ZICOND-NEXT: add a4, a5, a4 3693; RV32ZICOND-NEXT: snez a5, a1 3694; RV32ZICOND-NEXT: and a5, a5, a6 3695; RV32ZICOND-NEXT: mulhu a6, a1, a2 3696; RV32ZICOND-NEXT: snez a6, a6 3697; RV32ZICOND-NEXT: or a5, a5, a6 3698; RV32ZICOND-NEXT: mulhu a6, a0, a2 3699; RV32ZICOND-NEXT: add a4, a6, a4 3700; RV32ZICOND-NEXT: sltu a4, a4, a6 3701; RV32ZICOND-NEXT: mulhu a6, a3, a0 3702; RV32ZICOND-NEXT: snez a6, a6 3703; RV32ZICOND-NEXT: or a5, a5, a6 3704; RV32ZICOND-NEXT: or a4, a5, a4 3705; RV32ZICOND-NEXT: czero.nez a2, a2, a4 3706; RV32ZICOND-NEXT: czero.eqz a0, a0, a4 3707; RV32ZICOND-NEXT: czero.nez a3, a3, a4 3708; RV32ZICOND-NEXT: czero.eqz a1, a1, a4 3709; RV32ZICOND-NEXT: or a0, a0, a2 3710; RV32ZICOND-NEXT: or a1, a1, a3 3711; RV32ZICOND-NEXT: ret 3712; 3713; RV64ZICOND-LABEL: umulo.select.i64: 3714; RV64ZICOND: # %bb.0: # %entry 3715; RV64ZICOND-NEXT: mulhu a2, a0, a1 3716; RV64ZICOND-NEXT: czero.nez a1, a1, a2 3717; RV64ZICOND-NEXT: czero.eqz a0, a0, a2 3718; RV64ZICOND-NEXT: or a0, a0, a1 3719; RV64ZICOND-NEXT: ret 3720entry: 3721 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2) 3722 %obit = extractvalue {i64, i1} %t, 1 3723 %ret = select i1 %obit, i64 %v1, i64 %v2 3724 ret i64 %ret 3725} 3726 3727define i1 @umulo.not.i64(i64 %v1, i64 %v2) { 3728; RV32-LABEL: umulo.not.i64: 3729; RV32: # %bb.0: # %entry 3730; RV32-NEXT: mul a4, a3, a0 3731; RV32-NEXT: mul a5, a1, a2 3732; RV32-NEXT: mulhu a6, a0, a2 3733; RV32-NEXT: mulhu a0, a3, a0 3734; RV32-NEXT: snez a3, a3 3735; RV32-NEXT: mulhu a2, a1, a2 3736; RV32-NEXT: snez a1, a1 3737; RV32-NEXT: add a4, a5, a4 3738; RV32-NEXT: and a1, a1, a3 3739; RV32-NEXT: snez a2, a2 3740; RV32-NEXT: snez a0, a0 3741; RV32-NEXT: add a4, a6, a4 3742; RV32-NEXT: or a1, a1, a2 3743; RV32-NEXT: sltu a2, a4, a6 3744; RV32-NEXT: or a0, a1, a0 3745; RV32-NEXT: or a0, a0, a2 3746; RV32-NEXT: xori a0, a0, 1 3747; RV32-NEXT: ret 3748; 3749; RV64-LABEL: umulo.not.i64: 3750; RV64: # %bb.0: # %entry 3751; RV64-NEXT: mulhu a0, a0, a1 3752; RV64-NEXT: seqz a0, a0 3753; RV64-NEXT: ret 3754; 3755; RV32ZBA-LABEL: umulo.not.i64: 3756; RV32ZBA: # %bb.0: # %entry 3757; RV32ZBA-NEXT: mul a4, a3, a0 3758; RV32ZBA-NEXT: mul a5, a1, a2 3759; RV32ZBA-NEXT: mulhu a6, a0, a2 3760; RV32ZBA-NEXT: mulhu a0, a3, a0 3761; RV32ZBA-NEXT: snez a3, a3 3762; RV32ZBA-NEXT: mulhu a2, a1, a2 3763; RV32ZBA-NEXT: snez a1, a1 3764; RV32ZBA-NEXT: add a4, a5, a4 3765; RV32ZBA-NEXT: and a1, a1, a3 3766; RV32ZBA-NEXT: snez a2, a2 3767; RV32ZBA-NEXT: snez a0, a0 3768; RV32ZBA-NEXT: add a4, a6, a4 3769; RV32ZBA-NEXT: or a1, a1, a2 3770; RV32ZBA-NEXT: sltu a2, a4, a6 3771; RV32ZBA-NEXT: or a0, a1, a0 3772; RV32ZBA-NEXT: or a0, a0, a2 3773; RV32ZBA-NEXT: xori a0, a0, 1 3774; RV32ZBA-NEXT: ret 3775; 3776; RV64ZBA-LABEL: umulo.not.i64: 3777; RV64ZBA: # %bb.0: # %entry 3778; RV64ZBA-NEXT: mulhu a0, a0, a1 3779; RV64ZBA-NEXT: seqz a0, a0 3780; RV64ZBA-NEXT: ret 3781; 3782; RV32ZICOND-LABEL: umulo.not.i64: 3783; RV32ZICOND: # %bb.0: # %entry 3784; RV32ZICOND-NEXT: mul a4, a3, a0 3785; RV32ZICOND-NEXT: mul a5, a1, a2 3786; RV32ZICOND-NEXT: mulhu a6, a0, a2 3787; RV32ZICOND-NEXT: mulhu a0, a3, a0 3788; RV32ZICOND-NEXT: snez a3, a3 3789; RV32ZICOND-NEXT: mulhu a2, a1, a2 3790; RV32ZICOND-NEXT: snez a1, a1 3791; RV32ZICOND-NEXT: add a4, a5, a4 3792; RV32ZICOND-NEXT: and a1, a1, a3 3793; RV32ZICOND-NEXT: snez a2, a2 3794; RV32ZICOND-NEXT: snez a0, a0 3795; RV32ZICOND-NEXT: add a4, a6, a4 3796; RV32ZICOND-NEXT: or a1, a1, a2 3797; RV32ZICOND-NEXT: sltu a2, a4, a6 3798; RV32ZICOND-NEXT: or a0, a1, a0 3799; RV32ZICOND-NEXT: or a0, a0, a2 3800; RV32ZICOND-NEXT: xori a0, a0, 1 3801; RV32ZICOND-NEXT: ret 3802; 3803; RV64ZICOND-LABEL: umulo.not.i64: 3804; RV64ZICOND: # %bb.0: # %entry 3805; RV64ZICOND-NEXT: mulhu a0, a0, a1 3806; RV64ZICOND-NEXT: seqz a0, a0 3807; RV64ZICOND-NEXT: ret 3808entry: 3809 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2) 3810 %obit = extractvalue {i64, i1} %t, 1 3811 %ret = xor i1 %obit, true 3812 ret i1 %ret 3813} 3814 3815 3816; 3817; Check the use of the overflow bit in combination with a branch instruction. 3818; 3819define zeroext i1 @saddo.br.i32(i32 signext %v1, i32 signext %v2) { 3820; RV32-LABEL: saddo.br.i32: 3821; RV32: # %bb.0: # %entry 3822; RV32-NEXT: add a2, a0, a1 3823; RV32-NEXT: slt a0, a2, a0 3824; RV32-NEXT: slti a1, a1, 0 3825; RV32-NEXT: beq a1, a0, .LBB52_2 3826; RV32-NEXT: # %bb.1: # %overflow 3827; RV32-NEXT: li a0, 0 3828; RV32-NEXT: ret 3829; RV32-NEXT: .LBB52_2: # %continue 3830; RV32-NEXT: li a0, 1 3831; RV32-NEXT: ret 3832; 3833; RV64-LABEL: saddo.br.i32: 3834; RV64: # %bb.0: # %entry 3835; RV64-NEXT: add a2, a0, a1 3836; RV64-NEXT: addw a0, a0, a1 3837; RV64-NEXT: beq a0, a2, .LBB52_2 3838; RV64-NEXT: # %bb.1: # %overflow 3839; RV64-NEXT: li a0, 0 3840; RV64-NEXT: ret 3841; RV64-NEXT: .LBB52_2: # %continue 3842; RV64-NEXT: li a0, 1 3843; RV64-NEXT: ret 3844; 3845; RV32ZBA-LABEL: saddo.br.i32: 3846; RV32ZBA: # %bb.0: # %entry 3847; RV32ZBA-NEXT: add a2, a0, a1 3848; RV32ZBA-NEXT: slt a0, a2, a0 3849; RV32ZBA-NEXT: slti a1, a1, 0 3850; RV32ZBA-NEXT: beq a1, a0, .LBB52_2 3851; RV32ZBA-NEXT: # %bb.1: # %overflow 3852; RV32ZBA-NEXT: li a0, 0 3853; RV32ZBA-NEXT: ret 3854; RV32ZBA-NEXT: .LBB52_2: # %continue 3855; RV32ZBA-NEXT: li a0, 1 3856; RV32ZBA-NEXT: ret 3857; 3858; RV64ZBA-LABEL: saddo.br.i32: 3859; RV64ZBA: # %bb.0: # %entry 3860; RV64ZBA-NEXT: add a2, a0, a1 3861; RV64ZBA-NEXT: addw a0, a0, a1 3862; RV64ZBA-NEXT: beq a0, a2, .LBB52_2 3863; RV64ZBA-NEXT: # %bb.1: # %overflow 3864; RV64ZBA-NEXT: li a0, 0 3865; RV64ZBA-NEXT: ret 3866; RV64ZBA-NEXT: .LBB52_2: # %continue 3867; RV64ZBA-NEXT: li a0, 1 3868; RV64ZBA-NEXT: ret 3869; 3870; RV32ZICOND-LABEL: saddo.br.i32: 3871; RV32ZICOND: # %bb.0: # %entry 3872; RV32ZICOND-NEXT: add a2, a0, a1 3873; RV32ZICOND-NEXT: slt a0, a2, a0 3874; RV32ZICOND-NEXT: slti a1, a1, 0 3875; RV32ZICOND-NEXT: beq a1, a0, .LBB52_2 3876; RV32ZICOND-NEXT: # %bb.1: # %overflow 3877; RV32ZICOND-NEXT: li a0, 0 3878; RV32ZICOND-NEXT: ret 3879; RV32ZICOND-NEXT: .LBB52_2: # %continue 3880; RV32ZICOND-NEXT: li a0, 1 3881; RV32ZICOND-NEXT: ret 3882; 3883; RV64ZICOND-LABEL: saddo.br.i32: 3884; RV64ZICOND: # %bb.0: # %entry 3885; RV64ZICOND-NEXT: add a2, a0, a1 3886; RV64ZICOND-NEXT: addw a0, a0, a1 3887; RV64ZICOND-NEXT: beq a0, a2, .LBB52_2 3888; RV64ZICOND-NEXT: # %bb.1: # %overflow 3889; RV64ZICOND-NEXT: li a0, 0 3890; RV64ZICOND-NEXT: ret 3891; RV64ZICOND-NEXT: .LBB52_2: # %continue 3892; RV64ZICOND-NEXT: li a0, 1 3893; RV64ZICOND-NEXT: ret 3894entry: 3895 %t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2) 3896 %val = extractvalue {i32, i1} %t, 0 3897 %obit = extractvalue {i32, i1} %t, 1 3898 br i1 %obit, label %overflow, label %continue 3899 3900overflow: 3901 ret i1 false 3902 3903continue: 3904 ret i1 true 3905} 3906 3907define zeroext i1 @saddo.br.i64(i64 %v1, i64 %v2) { 3908; RV32-LABEL: saddo.br.i64: 3909; RV32: # %bb.0: # %entry 3910; RV32-NEXT: add a4, a1, a3 3911; RV32-NEXT: add a2, a0, a2 3912; RV32-NEXT: xor a3, a1, a3 3913; RV32-NEXT: sltu a0, a2, a0 3914; RV32-NEXT: add a0, a4, a0 3915; RV32-NEXT: xor a0, a1, a0 3916; RV32-NEXT: not a1, a3 3917; RV32-NEXT: and a0, a1, a0 3918; RV32-NEXT: bgez a0, .LBB53_2 3919; RV32-NEXT: # %bb.1: # %overflow 3920; RV32-NEXT: li a0, 0 3921; RV32-NEXT: ret 3922; RV32-NEXT: .LBB53_2: # %continue 3923; RV32-NEXT: li a0, 1 3924; RV32-NEXT: ret 3925; 3926; RV64-LABEL: saddo.br.i64: 3927; RV64: # %bb.0: # %entry 3928; RV64-NEXT: add a2, a0, a1 3929; RV64-NEXT: slt a0, a2, a0 3930; RV64-NEXT: slti a1, a1, 0 3931; RV64-NEXT: beq a1, a0, .LBB53_2 3932; RV64-NEXT: # %bb.1: # %overflow 3933; RV64-NEXT: li a0, 0 3934; RV64-NEXT: ret 3935; RV64-NEXT: .LBB53_2: # %continue 3936; RV64-NEXT: li a0, 1 3937; RV64-NEXT: ret 3938; 3939; RV32ZBA-LABEL: saddo.br.i64: 3940; RV32ZBA: # %bb.0: # %entry 3941; RV32ZBA-NEXT: add a4, a1, a3 3942; RV32ZBA-NEXT: add a2, a0, a2 3943; RV32ZBA-NEXT: xor a3, a1, a3 3944; RV32ZBA-NEXT: sltu a0, a2, a0 3945; RV32ZBA-NEXT: add a0, a4, a0 3946; RV32ZBA-NEXT: xor a0, a1, a0 3947; RV32ZBA-NEXT: not a1, a3 3948; RV32ZBA-NEXT: and a0, a1, a0 3949; RV32ZBA-NEXT: bgez a0, .LBB53_2 3950; RV32ZBA-NEXT: # %bb.1: # %overflow 3951; RV32ZBA-NEXT: li a0, 0 3952; RV32ZBA-NEXT: ret 3953; RV32ZBA-NEXT: .LBB53_2: # %continue 3954; RV32ZBA-NEXT: li a0, 1 3955; RV32ZBA-NEXT: ret 3956; 3957; RV64ZBA-LABEL: saddo.br.i64: 3958; RV64ZBA: # %bb.0: # %entry 3959; RV64ZBA-NEXT: add a2, a0, a1 3960; RV64ZBA-NEXT: slt a0, a2, a0 3961; RV64ZBA-NEXT: slti a1, a1, 0 3962; RV64ZBA-NEXT: beq a1, a0, .LBB53_2 3963; RV64ZBA-NEXT: # %bb.1: # %overflow 3964; RV64ZBA-NEXT: li a0, 0 3965; RV64ZBA-NEXT: ret 3966; RV64ZBA-NEXT: .LBB53_2: # %continue 3967; RV64ZBA-NEXT: li a0, 1 3968; RV64ZBA-NEXT: ret 3969; 3970; RV32ZICOND-LABEL: saddo.br.i64: 3971; RV32ZICOND: # %bb.0: # %entry 3972; RV32ZICOND-NEXT: add a4, a1, a3 3973; RV32ZICOND-NEXT: add a2, a0, a2 3974; RV32ZICOND-NEXT: xor a3, a1, a3 3975; RV32ZICOND-NEXT: sltu a0, a2, a0 3976; RV32ZICOND-NEXT: add a0, a4, a0 3977; RV32ZICOND-NEXT: xor a0, a1, a0 3978; RV32ZICOND-NEXT: not a1, a3 3979; RV32ZICOND-NEXT: and a0, a1, a0 3980; RV32ZICOND-NEXT: bgez a0, .LBB53_2 3981; RV32ZICOND-NEXT: # %bb.1: # %overflow 3982; RV32ZICOND-NEXT: li a0, 0 3983; RV32ZICOND-NEXT: ret 3984; RV32ZICOND-NEXT: .LBB53_2: # %continue 3985; RV32ZICOND-NEXT: li a0, 1 3986; RV32ZICOND-NEXT: ret 3987; 3988; RV64ZICOND-LABEL: saddo.br.i64: 3989; RV64ZICOND: # %bb.0: # %entry 3990; RV64ZICOND-NEXT: add a2, a0, a1 3991; RV64ZICOND-NEXT: slt a0, a2, a0 3992; RV64ZICOND-NEXT: slti a1, a1, 0 3993; RV64ZICOND-NEXT: beq a1, a0, .LBB53_2 3994; RV64ZICOND-NEXT: # %bb.1: # %overflow 3995; RV64ZICOND-NEXT: li a0, 0 3996; RV64ZICOND-NEXT: ret 3997; RV64ZICOND-NEXT: .LBB53_2: # %continue 3998; RV64ZICOND-NEXT: li a0, 1 3999; RV64ZICOND-NEXT: ret 4000entry: 4001 %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2) 4002 %val = extractvalue {i64, i1} %t, 0 4003 %obit = extractvalue {i64, i1} %t, 1 4004 br i1 %obit, label %overflow, label %continue 4005 4006overflow: 4007 ret i1 false 4008 4009continue: 4010 ret i1 true 4011} 4012 4013define zeroext i1 @uaddo.br.i32(i32 %v1, i32 %v2) { 4014; RV32-LABEL: uaddo.br.i32: 4015; RV32: # %bb.0: # %entry 4016; RV32-NEXT: add a1, a0, a1 4017; RV32-NEXT: bgeu a1, a0, .LBB54_2 4018; RV32-NEXT: # %bb.1: # %overflow 4019; RV32-NEXT: li a0, 0 4020; RV32-NEXT: ret 4021; RV32-NEXT: .LBB54_2: # %continue 4022; RV32-NEXT: li a0, 1 4023; RV32-NEXT: ret 4024; 4025; RV64-LABEL: uaddo.br.i32: 4026; RV64: # %bb.0: # %entry 4027; RV64-NEXT: addw a1, a0, a1 4028; RV64-NEXT: sext.w a0, a0 4029; RV64-NEXT: bgeu a1, a0, .LBB54_2 4030; RV64-NEXT: # %bb.1: # %overflow 4031; RV64-NEXT: li a0, 0 4032; RV64-NEXT: ret 4033; RV64-NEXT: .LBB54_2: # %continue 4034; RV64-NEXT: li a0, 1 4035; RV64-NEXT: ret 4036; 4037; RV32ZBA-LABEL: uaddo.br.i32: 4038; RV32ZBA: # %bb.0: # %entry 4039; RV32ZBA-NEXT: add a1, a0, a1 4040; RV32ZBA-NEXT: bgeu a1, a0, .LBB54_2 4041; RV32ZBA-NEXT: # %bb.1: # %overflow 4042; RV32ZBA-NEXT: li a0, 0 4043; RV32ZBA-NEXT: ret 4044; RV32ZBA-NEXT: .LBB54_2: # %continue 4045; RV32ZBA-NEXT: li a0, 1 4046; RV32ZBA-NEXT: ret 4047; 4048; RV64ZBA-LABEL: uaddo.br.i32: 4049; RV64ZBA: # %bb.0: # %entry 4050; RV64ZBA-NEXT: addw a1, a0, a1 4051; RV64ZBA-NEXT: sext.w a0, a0 4052; RV64ZBA-NEXT: bgeu a1, a0, .LBB54_2 4053; RV64ZBA-NEXT: # %bb.1: # %overflow 4054; RV64ZBA-NEXT: li a0, 0 4055; RV64ZBA-NEXT: ret 4056; RV64ZBA-NEXT: .LBB54_2: # %continue 4057; RV64ZBA-NEXT: li a0, 1 4058; RV64ZBA-NEXT: ret 4059; 4060; RV32ZICOND-LABEL: uaddo.br.i32: 4061; RV32ZICOND: # %bb.0: # %entry 4062; RV32ZICOND-NEXT: add a1, a0, a1 4063; RV32ZICOND-NEXT: bgeu a1, a0, .LBB54_2 4064; RV32ZICOND-NEXT: # %bb.1: # %overflow 4065; RV32ZICOND-NEXT: li a0, 0 4066; RV32ZICOND-NEXT: ret 4067; RV32ZICOND-NEXT: .LBB54_2: # %continue 4068; RV32ZICOND-NEXT: li a0, 1 4069; RV32ZICOND-NEXT: ret 4070; 4071; RV64ZICOND-LABEL: uaddo.br.i32: 4072; RV64ZICOND: # %bb.0: # %entry 4073; RV64ZICOND-NEXT: addw a1, a0, a1 4074; RV64ZICOND-NEXT: sext.w a0, a0 4075; RV64ZICOND-NEXT: bgeu a1, a0, .LBB54_2 4076; RV64ZICOND-NEXT: # %bb.1: # %overflow 4077; RV64ZICOND-NEXT: li a0, 0 4078; RV64ZICOND-NEXT: ret 4079; RV64ZICOND-NEXT: .LBB54_2: # %continue 4080; RV64ZICOND-NEXT: li a0, 1 4081; RV64ZICOND-NEXT: ret 4082entry: 4083 %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2) 4084 %val = extractvalue {i32, i1} %t, 0 4085 %obit = extractvalue {i32, i1} %t, 1 4086 br i1 %obit, label %overflow, label %continue 4087 4088overflow: 4089 ret i1 false 4090 4091continue: 4092 ret i1 true 4093} 4094 4095define zeroext i1 @uaddo.br.i64(i64 %v1, i64 %v2) { 4096; RV32-LABEL: uaddo.br.i64: 4097; RV32: # %bb.0: # %entry 4098; RV32-NEXT: add a3, a1, a3 4099; RV32-NEXT: add a2, a0, a2 4100; RV32-NEXT: sltu a0, a2, a0 4101; RV32-NEXT: add a2, a3, a0 4102; RV32-NEXT: beq a2, a1, .LBB55_2 4103; RV32-NEXT: # %bb.1: # %entry 4104; RV32-NEXT: sltu a0, a2, a1 4105; RV32-NEXT: .LBB55_2: # %entry 4106; RV32-NEXT: beqz a0, .LBB55_4 4107; RV32-NEXT: # %bb.3: # %overflow 4108; RV32-NEXT: li a0, 0 4109; RV32-NEXT: ret 4110; RV32-NEXT: .LBB55_4: # %continue 4111; RV32-NEXT: li a0, 1 4112; RV32-NEXT: ret 4113; 4114; RV64-LABEL: uaddo.br.i64: 4115; RV64: # %bb.0: # %entry 4116; RV64-NEXT: add a1, a0, a1 4117; RV64-NEXT: bgeu a1, a0, .LBB55_2 4118; RV64-NEXT: # %bb.1: # %overflow 4119; RV64-NEXT: li a0, 0 4120; RV64-NEXT: ret 4121; RV64-NEXT: .LBB55_2: # %continue 4122; RV64-NEXT: li a0, 1 4123; RV64-NEXT: ret 4124; 4125; RV32ZBA-LABEL: uaddo.br.i64: 4126; RV32ZBA: # %bb.0: # %entry 4127; RV32ZBA-NEXT: add a3, a1, a3 4128; RV32ZBA-NEXT: add a2, a0, a2 4129; RV32ZBA-NEXT: sltu a0, a2, a0 4130; RV32ZBA-NEXT: add a2, a3, a0 4131; RV32ZBA-NEXT: beq a2, a1, .LBB55_2 4132; RV32ZBA-NEXT: # %bb.1: # %entry 4133; RV32ZBA-NEXT: sltu a0, a2, a1 4134; RV32ZBA-NEXT: .LBB55_2: # %entry 4135; RV32ZBA-NEXT: beqz a0, .LBB55_4 4136; RV32ZBA-NEXT: # %bb.3: # %overflow 4137; RV32ZBA-NEXT: li a0, 0 4138; RV32ZBA-NEXT: ret 4139; RV32ZBA-NEXT: .LBB55_4: # %continue 4140; RV32ZBA-NEXT: li a0, 1 4141; RV32ZBA-NEXT: ret 4142; 4143; RV64ZBA-LABEL: uaddo.br.i64: 4144; RV64ZBA: # %bb.0: # %entry 4145; RV64ZBA-NEXT: add a1, a0, a1 4146; RV64ZBA-NEXT: bgeu a1, a0, .LBB55_2 4147; RV64ZBA-NEXT: # %bb.1: # %overflow 4148; RV64ZBA-NEXT: li a0, 0 4149; RV64ZBA-NEXT: ret 4150; RV64ZBA-NEXT: .LBB55_2: # %continue 4151; RV64ZBA-NEXT: li a0, 1 4152; RV64ZBA-NEXT: ret 4153; 4154; RV32ZICOND-LABEL: uaddo.br.i64: 4155; RV32ZICOND: # %bb.0: # %entry 4156; RV32ZICOND-NEXT: add a3, a1, a3 4157; RV32ZICOND-NEXT: add a2, a0, a2 4158; RV32ZICOND-NEXT: sltu a0, a2, a0 4159; RV32ZICOND-NEXT: add a3, a3, a0 4160; RV32ZICOND-NEXT: xor a2, a3, a1 4161; RV32ZICOND-NEXT: sltu a1, a3, a1 4162; RV32ZICOND-NEXT: czero.eqz a1, a1, a2 4163; RV32ZICOND-NEXT: czero.nez a0, a0, a2 4164; RV32ZICOND-NEXT: or a0, a0, a1 4165; RV32ZICOND-NEXT: beqz a0, .LBB55_2 4166; RV32ZICOND-NEXT: # %bb.1: # %overflow 4167; RV32ZICOND-NEXT: li a0, 0 4168; RV32ZICOND-NEXT: ret 4169; RV32ZICOND-NEXT: .LBB55_2: # %continue 4170; RV32ZICOND-NEXT: li a0, 1 4171; RV32ZICOND-NEXT: ret 4172; 4173; RV64ZICOND-LABEL: uaddo.br.i64: 4174; RV64ZICOND: # %bb.0: # %entry 4175; RV64ZICOND-NEXT: add a1, a0, a1 4176; RV64ZICOND-NEXT: bgeu a1, a0, .LBB55_2 4177; RV64ZICOND-NEXT: # %bb.1: # %overflow 4178; RV64ZICOND-NEXT: li a0, 0 4179; RV64ZICOND-NEXT: ret 4180; RV64ZICOND-NEXT: .LBB55_2: # %continue 4181; RV64ZICOND-NEXT: li a0, 1 4182; RV64ZICOND-NEXT: ret 4183entry: 4184 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2) 4185 %val = extractvalue {i64, i1} %t, 0 4186 %obit = extractvalue {i64, i1} %t, 1 4187 br i1 %obit, label %overflow, label %continue 4188 4189overflow: 4190 ret i1 false 4191 4192continue: 4193 ret i1 true 4194} 4195 4196define zeroext i1 @ssubo.br.i32(i32 signext %v1, i32 signext %v2) { 4197; RV32-LABEL: ssubo.br.i32: 4198; RV32: # %bb.0: # %entry 4199; RV32-NEXT: sgtz a2, a1 4200; RV32-NEXT: sub a1, a0, a1 4201; RV32-NEXT: slt a0, a1, a0 4202; RV32-NEXT: beq a2, a0, .LBB56_2 4203; RV32-NEXT: # %bb.1: # %overflow 4204; RV32-NEXT: li a0, 0 4205; RV32-NEXT: ret 4206; RV32-NEXT: .LBB56_2: # %continue 4207; RV32-NEXT: li a0, 1 4208; RV32-NEXT: ret 4209; 4210; RV64-LABEL: ssubo.br.i32: 4211; RV64: # %bb.0: # %entry 4212; RV64-NEXT: sub a2, a0, a1 4213; RV64-NEXT: subw a0, a0, a1 4214; RV64-NEXT: beq a0, a2, .LBB56_2 4215; RV64-NEXT: # %bb.1: # %overflow 4216; RV64-NEXT: li a0, 0 4217; RV64-NEXT: ret 4218; RV64-NEXT: .LBB56_2: # %continue 4219; RV64-NEXT: li a0, 1 4220; RV64-NEXT: ret 4221; 4222; RV32ZBA-LABEL: ssubo.br.i32: 4223; RV32ZBA: # %bb.0: # %entry 4224; RV32ZBA-NEXT: sgtz a2, a1 4225; RV32ZBA-NEXT: sub a1, a0, a1 4226; RV32ZBA-NEXT: slt a0, a1, a0 4227; RV32ZBA-NEXT: beq a2, a0, .LBB56_2 4228; RV32ZBA-NEXT: # %bb.1: # %overflow 4229; RV32ZBA-NEXT: li a0, 0 4230; RV32ZBA-NEXT: ret 4231; RV32ZBA-NEXT: .LBB56_2: # %continue 4232; RV32ZBA-NEXT: li a0, 1 4233; RV32ZBA-NEXT: ret 4234; 4235; RV64ZBA-LABEL: ssubo.br.i32: 4236; RV64ZBA: # %bb.0: # %entry 4237; RV64ZBA-NEXT: sub a2, a0, a1 4238; RV64ZBA-NEXT: subw a0, a0, a1 4239; RV64ZBA-NEXT: beq a0, a2, .LBB56_2 4240; RV64ZBA-NEXT: # %bb.1: # %overflow 4241; RV64ZBA-NEXT: li a0, 0 4242; RV64ZBA-NEXT: ret 4243; RV64ZBA-NEXT: .LBB56_2: # %continue 4244; RV64ZBA-NEXT: li a0, 1 4245; RV64ZBA-NEXT: ret 4246; 4247; RV32ZICOND-LABEL: ssubo.br.i32: 4248; RV32ZICOND: # %bb.0: # %entry 4249; RV32ZICOND-NEXT: sgtz a2, a1 4250; RV32ZICOND-NEXT: sub a1, a0, a1 4251; RV32ZICOND-NEXT: slt a0, a1, a0 4252; RV32ZICOND-NEXT: beq a2, a0, .LBB56_2 4253; RV32ZICOND-NEXT: # %bb.1: # %overflow 4254; RV32ZICOND-NEXT: li a0, 0 4255; RV32ZICOND-NEXT: ret 4256; RV32ZICOND-NEXT: .LBB56_2: # %continue 4257; RV32ZICOND-NEXT: li a0, 1 4258; RV32ZICOND-NEXT: ret 4259; 4260; RV64ZICOND-LABEL: ssubo.br.i32: 4261; RV64ZICOND: # %bb.0: # %entry 4262; RV64ZICOND-NEXT: sub a2, a0, a1 4263; RV64ZICOND-NEXT: subw a0, a0, a1 4264; RV64ZICOND-NEXT: beq a0, a2, .LBB56_2 4265; RV64ZICOND-NEXT: # %bb.1: # %overflow 4266; RV64ZICOND-NEXT: li a0, 0 4267; RV64ZICOND-NEXT: ret 4268; RV64ZICOND-NEXT: .LBB56_2: # %continue 4269; RV64ZICOND-NEXT: li a0, 1 4270; RV64ZICOND-NEXT: ret 4271entry: 4272 %t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2) 4273 %val = extractvalue {i32, i1} %t, 0 4274 %obit = extractvalue {i32, i1} %t, 1 4275 br i1 %obit, label %overflow, label %continue 4276 4277overflow: 4278 ret i1 false 4279 4280continue: 4281 ret i1 true 4282} 4283 4284define zeroext i1 @ssubo.br.i64(i64 %v1, i64 %v2) { 4285; RV32-LABEL: ssubo.br.i64: 4286; RV32: # %bb.0: # %entry 4287; RV32-NEXT: sltu a0, a0, a2 4288; RV32-NEXT: sub a2, a1, a3 4289; RV32-NEXT: sub a2, a2, a0 4290; RV32-NEXT: xor a2, a1, a2 4291; RV32-NEXT: xor a1, a1, a3 4292; RV32-NEXT: and a1, a1, a2 4293; RV32-NEXT: bgez a1, .LBB57_2 4294; RV32-NEXT: # %bb.1: # %overflow 4295; RV32-NEXT: li a0, 0 4296; RV32-NEXT: ret 4297; RV32-NEXT: .LBB57_2: # %continue 4298; RV32-NEXT: li a0, 1 4299; RV32-NEXT: ret 4300; 4301; RV64-LABEL: ssubo.br.i64: 4302; RV64: # %bb.0: # %entry 4303; RV64-NEXT: sgtz a2, a1 4304; RV64-NEXT: sub a1, a0, a1 4305; RV64-NEXT: slt a0, a1, a0 4306; RV64-NEXT: beq a2, a0, .LBB57_2 4307; RV64-NEXT: # %bb.1: # %overflow 4308; RV64-NEXT: li a0, 0 4309; RV64-NEXT: ret 4310; RV64-NEXT: .LBB57_2: # %continue 4311; RV64-NEXT: li a0, 1 4312; RV64-NEXT: ret 4313; 4314; RV32ZBA-LABEL: ssubo.br.i64: 4315; RV32ZBA: # %bb.0: # %entry 4316; RV32ZBA-NEXT: sltu a0, a0, a2 4317; RV32ZBA-NEXT: sub a2, a1, a3 4318; RV32ZBA-NEXT: sub a2, a2, a0 4319; RV32ZBA-NEXT: xor a2, a1, a2 4320; RV32ZBA-NEXT: xor a1, a1, a3 4321; RV32ZBA-NEXT: and a1, a1, a2 4322; RV32ZBA-NEXT: bgez a1, .LBB57_2 4323; RV32ZBA-NEXT: # %bb.1: # %overflow 4324; RV32ZBA-NEXT: li a0, 0 4325; RV32ZBA-NEXT: ret 4326; RV32ZBA-NEXT: .LBB57_2: # %continue 4327; RV32ZBA-NEXT: li a0, 1 4328; RV32ZBA-NEXT: ret 4329; 4330; RV64ZBA-LABEL: ssubo.br.i64: 4331; RV64ZBA: # %bb.0: # %entry 4332; RV64ZBA-NEXT: sgtz a2, a1 4333; RV64ZBA-NEXT: sub a1, a0, a1 4334; RV64ZBA-NEXT: slt a0, a1, a0 4335; RV64ZBA-NEXT: beq a2, a0, .LBB57_2 4336; RV64ZBA-NEXT: # %bb.1: # %overflow 4337; RV64ZBA-NEXT: li a0, 0 4338; RV64ZBA-NEXT: ret 4339; RV64ZBA-NEXT: .LBB57_2: # %continue 4340; RV64ZBA-NEXT: li a0, 1 4341; RV64ZBA-NEXT: ret 4342; 4343; RV32ZICOND-LABEL: ssubo.br.i64: 4344; RV32ZICOND: # %bb.0: # %entry 4345; RV32ZICOND-NEXT: sltu a0, a0, a2 4346; RV32ZICOND-NEXT: sub a2, a1, a3 4347; RV32ZICOND-NEXT: sub a2, a2, a0 4348; RV32ZICOND-NEXT: xor a2, a1, a2 4349; RV32ZICOND-NEXT: xor a1, a1, a3 4350; RV32ZICOND-NEXT: and a1, a1, a2 4351; RV32ZICOND-NEXT: bgez a1, .LBB57_2 4352; RV32ZICOND-NEXT: # %bb.1: # %overflow 4353; RV32ZICOND-NEXT: li a0, 0 4354; RV32ZICOND-NEXT: ret 4355; RV32ZICOND-NEXT: .LBB57_2: # %continue 4356; RV32ZICOND-NEXT: li a0, 1 4357; RV32ZICOND-NEXT: ret 4358; 4359; RV64ZICOND-LABEL: ssubo.br.i64: 4360; RV64ZICOND: # %bb.0: # %entry 4361; RV64ZICOND-NEXT: sgtz a2, a1 4362; RV64ZICOND-NEXT: sub a1, a0, a1 4363; RV64ZICOND-NEXT: slt a0, a1, a0 4364; RV64ZICOND-NEXT: beq a2, a0, .LBB57_2 4365; RV64ZICOND-NEXT: # %bb.1: # %overflow 4366; RV64ZICOND-NEXT: li a0, 0 4367; RV64ZICOND-NEXT: ret 4368; RV64ZICOND-NEXT: .LBB57_2: # %continue 4369; RV64ZICOND-NEXT: li a0, 1 4370; RV64ZICOND-NEXT: ret 4371entry: 4372 %t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2) 4373 %val = extractvalue {i64, i1} %t, 0 4374 %obit = extractvalue {i64, i1} %t, 1 4375 br i1 %obit, label %overflow, label %continue 4376 4377overflow: 4378 ret i1 false 4379 4380continue: 4381 ret i1 true 4382} 4383 4384define zeroext i1 @usubo.br.i32(i32 signext %v1, i32 signext %v2) { 4385; RV32-LABEL: usubo.br.i32: 4386; RV32: # %bb.0: # %entry 4387; RV32-NEXT: sub a1, a0, a1 4388; RV32-NEXT: bgeu a0, a1, .LBB58_2 4389; RV32-NEXT: # %bb.1: # %overflow 4390; RV32-NEXT: li a0, 0 4391; RV32-NEXT: ret 4392; RV32-NEXT: .LBB58_2: # %continue 4393; RV32-NEXT: li a0, 1 4394; RV32-NEXT: ret 4395; 4396; RV64-LABEL: usubo.br.i32: 4397; RV64: # %bb.0: # %entry 4398; RV64-NEXT: subw a1, a0, a1 4399; RV64-NEXT: bgeu a0, a1, .LBB58_2 4400; RV64-NEXT: # %bb.1: # %overflow 4401; RV64-NEXT: li a0, 0 4402; RV64-NEXT: ret 4403; RV64-NEXT: .LBB58_2: # %continue 4404; RV64-NEXT: li a0, 1 4405; RV64-NEXT: ret 4406; 4407; RV32ZBA-LABEL: usubo.br.i32: 4408; RV32ZBA: # %bb.0: # %entry 4409; RV32ZBA-NEXT: sub a1, a0, a1 4410; RV32ZBA-NEXT: bgeu a0, a1, .LBB58_2 4411; RV32ZBA-NEXT: # %bb.1: # %overflow 4412; RV32ZBA-NEXT: li a0, 0 4413; RV32ZBA-NEXT: ret 4414; RV32ZBA-NEXT: .LBB58_2: # %continue 4415; RV32ZBA-NEXT: li a0, 1 4416; RV32ZBA-NEXT: ret 4417; 4418; RV64ZBA-LABEL: usubo.br.i32: 4419; RV64ZBA: # %bb.0: # %entry 4420; RV64ZBA-NEXT: subw a1, a0, a1 4421; RV64ZBA-NEXT: bgeu a0, a1, .LBB58_2 4422; RV64ZBA-NEXT: # %bb.1: # %overflow 4423; RV64ZBA-NEXT: li a0, 0 4424; RV64ZBA-NEXT: ret 4425; RV64ZBA-NEXT: .LBB58_2: # %continue 4426; RV64ZBA-NEXT: li a0, 1 4427; RV64ZBA-NEXT: ret 4428; 4429; RV32ZICOND-LABEL: usubo.br.i32: 4430; RV32ZICOND: # %bb.0: # %entry 4431; RV32ZICOND-NEXT: sub a1, a0, a1 4432; RV32ZICOND-NEXT: bgeu a0, a1, .LBB58_2 4433; RV32ZICOND-NEXT: # %bb.1: # %overflow 4434; RV32ZICOND-NEXT: li a0, 0 4435; RV32ZICOND-NEXT: ret 4436; RV32ZICOND-NEXT: .LBB58_2: # %continue 4437; RV32ZICOND-NEXT: li a0, 1 4438; RV32ZICOND-NEXT: ret 4439; 4440; RV64ZICOND-LABEL: usubo.br.i32: 4441; RV64ZICOND: # %bb.0: # %entry 4442; RV64ZICOND-NEXT: subw a1, a0, a1 4443; RV64ZICOND-NEXT: bgeu a0, a1, .LBB58_2 4444; RV64ZICOND-NEXT: # %bb.1: # %overflow 4445; RV64ZICOND-NEXT: li a0, 0 4446; RV64ZICOND-NEXT: ret 4447; RV64ZICOND-NEXT: .LBB58_2: # %continue 4448; RV64ZICOND-NEXT: li a0, 1 4449; RV64ZICOND-NEXT: ret 4450entry: 4451 %t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2) 4452 %val = extractvalue {i32, i1} %t, 0 4453 %obit = extractvalue {i32, i1} %t, 1 4454 br i1 %obit, label %overflow, label %continue 4455 4456overflow: 4457 ret i1 false 4458 4459continue: 4460 ret i1 true 4461} 4462 4463define zeroext i1 @usubo.br.i64(i64 %v1, i64 %v2) { 4464; RV32-LABEL: usubo.br.i64: 4465; RV32: # %bb.0: # %entry 4466; RV32-NEXT: sltu a4, a0, a2 4467; RV32-NEXT: sub a3, a1, a3 4468; RV32-NEXT: sub a3, a3, a4 4469; RV32-NEXT: beq a3, a1, .LBB59_3 4470; RV32-NEXT: # %bb.1: # %entry 4471; RV32-NEXT: sltu a0, a1, a3 4472; RV32-NEXT: bnez a0, .LBB59_4 4473; RV32-NEXT: .LBB59_2: # %continue 4474; RV32-NEXT: li a0, 1 4475; RV32-NEXT: ret 4476; RV32-NEXT: .LBB59_3: 4477; RV32-NEXT: sub a1, a0, a2 4478; RV32-NEXT: sltu a0, a0, a1 4479; RV32-NEXT: beqz a0, .LBB59_2 4480; RV32-NEXT: .LBB59_4: # %overflow 4481; RV32-NEXT: li a0, 0 4482; RV32-NEXT: ret 4483; 4484; RV64-LABEL: usubo.br.i64: 4485; RV64: # %bb.0: # %entry 4486; RV64-NEXT: sub a1, a0, a1 4487; RV64-NEXT: bgeu a0, a1, .LBB59_2 4488; RV64-NEXT: # %bb.1: # %overflow 4489; RV64-NEXT: li a0, 0 4490; RV64-NEXT: ret 4491; RV64-NEXT: .LBB59_2: # %continue 4492; RV64-NEXT: li a0, 1 4493; RV64-NEXT: ret 4494; 4495; RV32ZBA-LABEL: usubo.br.i64: 4496; RV32ZBA: # %bb.0: # %entry 4497; RV32ZBA-NEXT: sltu a4, a0, a2 4498; RV32ZBA-NEXT: sub a3, a1, a3 4499; RV32ZBA-NEXT: sub a3, a3, a4 4500; RV32ZBA-NEXT: beq a3, a1, .LBB59_3 4501; RV32ZBA-NEXT: # %bb.1: # %entry 4502; RV32ZBA-NEXT: sltu a0, a1, a3 4503; RV32ZBA-NEXT: bnez a0, .LBB59_4 4504; RV32ZBA-NEXT: .LBB59_2: # %continue 4505; RV32ZBA-NEXT: li a0, 1 4506; RV32ZBA-NEXT: ret 4507; RV32ZBA-NEXT: .LBB59_3: 4508; RV32ZBA-NEXT: sub a1, a0, a2 4509; RV32ZBA-NEXT: sltu a0, a0, a1 4510; RV32ZBA-NEXT: beqz a0, .LBB59_2 4511; RV32ZBA-NEXT: .LBB59_4: # %overflow 4512; RV32ZBA-NEXT: li a0, 0 4513; RV32ZBA-NEXT: ret 4514; 4515; RV64ZBA-LABEL: usubo.br.i64: 4516; RV64ZBA: # %bb.0: # %entry 4517; RV64ZBA-NEXT: sub a1, a0, a1 4518; RV64ZBA-NEXT: bgeu a0, a1, .LBB59_2 4519; RV64ZBA-NEXT: # %bb.1: # %overflow 4520; RV64ZBA-NEXT: li a0, 0 4521; RV64ZBA-NEXT: ret 4522; RV64ZBA-NEXT: .LBB59_2: # %continue 4523; RV64ZBA-NEXT: li a0, 1 4524; RV64ZBA-NEXT: ret 4525; 4526; RV32ZICOND-LABEL: usubo.br.i64: 4527; RV32ZICOND: # %bb.0: # %entry 4528; RV32ZICOND-NEXT: sltu a4, a0, a2 4529; RV32ZICOND-NEXT: sub a3, a1, a3 4530; RV32ZICOND-NEXT: sub a2, a0, a2 4531; RV32ZICOND-NEXT: sub a3, a3, a4 4532; RV32ZICOND-NEXT: sltu a0, a0, a2 4533; RV32ZICOND-NEXT: xor a2, a3, a1 4534; RV32ZICOND-NEXT: sltu a1, a1, a3 4535; RV32ZICOND-NEXT: czero.eqz a1, a1, a2 4536; RV32ZICOND-NEXT: czero.nez a0, a0, a2 4537; RV32ZICOND-NEXT: or a0, a0, a1 4538; RV32ZICOND-NEXT: beqz a0, .LBB59_2 4539; RV32ZICOND-NEXT: # %bb.1: # %overflow 4540; RV32ZICOND-NEXT: li a0, 0 4541; RV32ZICOND-NEXT: ret 4542; RV32ZICOND-NEXT: .LBB59_2: # %continue 4543; RV32ZICOND-NEXT: li a0, 1 4544; RV32ZICOND-NEXT: ret 4545; 4546; RV64ZICOND-LABEL: usubo.br.i64: 4547; RV64ZICOND: # %bb.0: # %entry 4548; RV64ZICOND-NEXT: sub a1, a0, a1 4549; RV64ZICOND-NEXT: bgeu a0, a1, .LBB59_2 4550; RV64ZICOND-NEXT: # %bb.1: # %overflow 4551; RV64ZICOND-NEXT: li a0, 0 4552; RV64ZICOND-NEXT: ret 4553; RV64ZICOND-NEXT: .LBB59_2: # %continue 4554; RV64ZICOND-NEXT: li a0, 1 4555; RV64ZICOND-NEXT: ret 4556entry: 4557 %t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2) 4558 %val = extractvalue {i64, i1} %t, 0 4559 %obit = extractvalue {i64, i1} %t, 1 4560 br i1 %obit, label %overflow, label %continue 4561 4562overflow: 4563 ret i1 false 4564 4565continue: 4566 ret i1 true 4567} 4568 4569define zeroext i1 @smulo.br.i32(i32 signext %v1, i32 signext %v2) { 4570; RV32-LABEL: smulo.br.i32: 4571; RV32: # %bb.0: # %entry 4572; RV32-NEXT: mulh a2, a0, a1 4573; RV32-NEXT: mul a0, a0, a1 4574; RV32-NEXT: srai a0, a0, 31 4575; RV32-NEXT: beq a2, a0, .LBB60_2 4576; RV32-NEXT: # %bb.1: # %overflow 4577; RV32-NEXT: li a0, 0 4578; RV32-NEXT: ret 4579; RV32-NEXT: .LBB60_2: # %continue 4580; RV32-NEXT: li a0, 1 4581; RV32-NEXT: ret 4582; 4583; RV64-LABEL: smulo.br.i32: 4584; RV64: # %bb.0: # %entry 4585; RV64-NEXT: mul a2, a0, a1 4586; RV64-NEXT: mulw a0, a0, a1 4587; RV64-NEXT: beq a0, a2, .LBB60_2 4588; RV64-NEXT: # %bb.1: # %overflow 4589; RV64-NEXT: li a0, 0 4590; RV64-NEXT: ret 4591; RV64-NEXT: .LBB60_2: # %continue 4592; RV64-NEXT: li a0, 1 4593; RV64-NEXT: ret 4594; 4595; RV32ZBA-LABEL: smulo.br.i32: 4596; RV32ZBA: # %bb.0: # %entry 4597; RV32ZBA-NEXT: mulh a2, a0, a1 4598; RV32ZBA-NEXT: mul a0, a0, a1 4599; RV32ZBA-NEXT: srai a0, a0, 31 4600; RV32ZBA-NEXT: beq a2, a0, .LBB60_2 4601; RV32ZBA-NEXT: # %bb.1: # %overflow 4602; RV32ZBA-NEXT: li a0, 0 4603; RV32ZBA-NEXT: ret 4604; RV32ZBA-NEXT: .LBB60_2: # %continue 4605; RV32ZBA-NEXT: li a0, 1 4606; RV32ZBA-NEXT: ret 4607; 4608; RV64ZBA-LABEL: smulo.br.i32: 4609; RV64ZBA: # %bb.0: # %entry 4610; RV64ZBA-NEXT: mul a2, a0, a1 4611; RV64ZBA-NEXT: mulw a0, a0, a1 4612; RV64ZBA-NEXT: beq a0, a2, .LBB60_2 4613; RV64ZBA-NEXT: # %bb.1: # %overflow 4614; RV64ZBA-NEXT: li a0, 0 4615; RV64ZBA-NEXT: ret 4616; RV64ZBA-NEXT: .LBB60_2: # %continue 4617; RV64ZBA-NEXT: li a0, 1 4618; RV64ZBA-NEXT: ret 4619; 4620; RV32ZICOND-LABEL: smulo.br.i32: 4621; RV32ZICOND: # %bb.0: # %entry 4622; RV32ZICOND-NEXT: mulh a2, a0, a1 4623; RV32ZICOND-NEXT: mul a0, a0, a1 4624; RV32ZICOND-NEXT: srai a0, a0, 31 4625; RV32ZICOND-NEXT: beq a2, a0, .LBB60_2 4626; RV32ZICOND-NEXT: # %bb.1: # %overflow 4627; RV32ZICOND-NEXT: li a0, 0 4628; RV32ZICOND-NEXT: ret 4629; RV32ZICOND-NEXT: .LBB60_2: # %continue 4630; RV32ZICOND-NEXT: li a0, 1 4631; RV32ZICOND-NEXT: ret 4632; 4633; RV64ZICOND-LABEL: smulo.br.i32: 4634; RV64ZICOND: # %bb.0: # %entry 4635; RV64ZICOND-NEXT: mul a2, a0, a1 4636; RV64ZICOND-NEXT: mulw a0, a0, a1 4637; RV64ZICOND-NEXT: beq a0, a2, .LBB60_2 4638; RV64ZICOND-NEXT: # %bb.1: # %overflow 4639; RV64ZICOND-NEXT: li a0, 0 4640; RV64ZICOND-NEXT: ret 4641; RV64ZICOND-NEXT: .LBB60_2: # %continue 4642; RV64ZICOND-NEXT: li a0, 1 4643; RV64ZICOND-NEXT: ret 4644entry: 4645 %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2) 4646 %val = extractvalue {i32, i1} %t, 0 4647 %obit = extractvalue {i32, i1} %t, 1 4648 br i1 %obit, label %overflow, label %continue 4649 4650overflow: 4651 ret i1 false 4652 4653continue: 4654 ret i1 true 4655} 4656 4657define zeroext i1 @smulo.br.i64(i64 %v1, i64 %v2) { 4658; RV32-LABEL: smulo.br.i64: 4659; RV32: # %bb.0: # %entry 4660; RV32-NEXT: mulhu a4, a0, a2 4661; RV32-NEXT: mul a5, a1, a2 4662; RV32-NEXT: mulhsu a2, a1, a2 4663; RV32-NEXT: mul a6, a3, a0 4664; RV32-NEXT: mulhsu a0, a3, a0 4665; RV32-NEXT: mulh a7, a1, a3 4666; RV32-NEXT: mul a1, a1, a3 4667; RV32-NEXT: add a4, a5, a4 4668; RV32-NEXT: sltu a3, a4, a5 4669; RV32-NEXT: add a4, a6, a4 4670; RV32-NEXT: add a2, a2, a3 4671; RV32-NEXT: sltu a3, a4, a6 4672; RV32-NEXT: srai a4, a4, 31 4673; RV32-NEXT: add a0, a0, a3 4674; RV32-NEXT: srai a3, a2, 31 4675; RV32-NEXT: add a5, a2, a0 4676; RV32-NEXT: srai a0, a0, 31 4677; RV32-NEXT: sltu a2, a5, a2 4678; RV32-NEXT: add a0, a3, a0 4679; RV32-NEXT: add a5, a1, a5 4680; RV32-NEXT: add a0, a0, a2 4681; RV32-NEXT: sltu a1, a5, a1 4682; RV32-NEXT: add a0, a7, a0 4683; RV32-NEXT: add a0, a0, a1 4684; RV32-NEXT: xor a0, a0, a4 4685; RV32-NEXT: xor a4, a5, a4 4686; RV32-NEXT: or a0, a4, a0 4687; RV32-NEXT: beqz a0, .LBB61_2 4688; RV32-NEXT: # %bb.1: # %overflow 4689; RV32-NEXT: li a0, 0 4690; RV32-NEXT: ret 4691; RV32-NEXT: .LBB61_2: # %continue 4692; RV32-NEXT: li a0, 1 4693; RV32-NEXT: ret 4694; 4695; RV64-LABEL: smulo.br.i64: 4696; RV64: # %bb.0: # %entry 4697; RV64-NEXT: mulh a2, a0, a1 4698; RV64-NEXT: mul a0, a0, a1 4699; RV64-NEXT: srai a0, a0, 63 4700; RV64-NEXT: beq a2, a0, .LBB61_2 4701; RV64-NEXT: # %bb.1: # %overflow 4702; RV64-NEXT: li a0, 0 4703; RV64-NEXT: ret 4704; RV64-NEXT: .LBB61_2: # %continue 4705; RV64-NEXT: li a0, 1 4706; RV64-NEXT: ret 4707; 4708; RV32ZBA-LABEL: smulo.br.i64: 4709; RV32ZBA: # %bb.0: # %entry 4710; RV32ZBA-NEXT: mulhu a4, a0, a2 4711; RV32ZBA-NEXT: mul a5, a1, a2 4712; RV32ZBA-NEXT: mulhsu a2, a1, a2 4713; RV32ZBA-NEXT: mul a6, a3, a0 4714; RV32ZBA-NEXT: mulhsu a0, a3, a0 4715; RV32ZBA-NEXT: mulh a7, a1, a3 4716; RV32ZBA-NEXT: mul a1, a1, a3 4717; RV32ZBA-NEXT: add a4, a5, a4 4718; RV32ZBA-NEXT: sltu a3, a4, a5 4719; RV32ZBA-NEXT: add a4, a6, a4 4720; RV32ZBA-NEXT: add a2, a2, a3 4721; RV32ZBA-NEXT: sltu a3, a4, a6 4722; RV32ZBA-NEXT: srai a4, a4, 31 4723; RV32ZBA-NEXT: add a0, a0, a3 4724; RV32ZBA-NEXT: srai a3, a2, 31 4725; RV32ZBA-NEXT: add a5, a2, a0 4726; RV32ZBA-NEXT: srai a0, a0, 31 4727; RV32ZBA-NEXT: sltu a2, a5, a2 4728; RV32ZBA-NEXT: add a0, a3, a0 4729; RV32ZBA-NEXT: add a5, a1, a5 4730; RV32ZBA-NEXT: add a0, a0, a2 4731; RV32ZBA-NEXT: sltu a1, a5, a1 4732; RV32ZBA-NEXT: add a0, a7, a0 4733; RV32ZBA-NEXT: add a0, a0, a1 4734; RV32ZBA-NEXT: xor a0, a0, a4 4735; RV32ZBA-NEXT: xor a4, a5, a4 4736; RV32ZBA-NEXT: or a0, a4, a0 4737; RV32ZBA-NEXT: beqz a0, .LBB61_2 4738; RV32ZBA-NEXT: # %bb.1: # %overflow 4739; RV32ZBA-NEXT: li a0, 0 4740; RV32ZBA-NEXT: ret 4741; RV32ZBA-NEXT: .LBB61_2: # %continue 4742; RV32ZBA-NEXT: li a0, 1 4743; RV32ZBA-NEXT: ret 4744; 4745; RV64ZBA-LABEL: smulo.br.i64: 4746; RV64ZBA: # %bb.0: # %entry 4747; RV64ZBA-NEXT: mulh a2, a0, a1 4748; RV64ZBA-NEXT: mul a0, a0, a1 4749; RV64ZBA-NEXT: srai a0, a0, 63 4750; RV64ZBA-NEXT: beq a2, a0, .LBB61_2 4751; RV64ZBA-NEXT: # %bb.1: # %overflow 4752; RV64ZBA-NEXT: li a0, 0 4753; RV64ZBA-NEXT: ret 4754; RV64ZBA-NEXT: .LBB61_2: # %continue 4755; RV64ZBA-NEXT: li a0, 1 4756; RV64ZBA-NEXT: ret 4757; 4758; RV32ZICOND-LABEL: smulo.br.i64: 4759; RV32ZICOND: # %bb.0: # %entry 4760; RV32ZICOND-NEXT: mulhu a4, a0, a2 4761; RV32ZICOND-NEXT: mul a5, a1, a2 4762; RV32ZICOND-NEXT: mulhsu a2, a1, a2 4763; RV32ZICOND-NEXT: mul a6, a3, a0 4764; RV32ZICOND-NEXT: mulhsu a0, a3, a0 4765; RV32ZICOND-NEXT: mulh a7, a1, a3 4766; RV32ZICOND-NEXT: mul a1, a1, a3 4767; RV32ZICOND-NEXT: add a4, a5, a4 4768; RV32ZICOND-NEXT: sltu a3, a4, a5 4769; RV32ZICOND-NEXT: add a4, a6, a4 4770; RV32ZICOND-NEXT: add a2, a2, a3 4771; RV32ZICOND-NEXT: sltu a3, a4, a6 4772; RV32ZICOND-NEXT: srai a4, a4, 31 4773; RV32ZICOND-NEXT: add a0, a0, a3 4774; RV32ZICOND-NEXT: srai a3, a2, 31 4775; RV32ZICOND-NEXT: add a5, a2, a0 4776; RV32ZICOND-NEXT: srai a0, a0, 31 4777; RV32ZICOND-NEXT: sltu a2, a5, a2 4778; RV32ZICOND-NEXT: add a0, a3, a0 4779; RV32ZICOND-NEXT: add a5, a1, a5 4780; RV32ZICOND-NEXT: add a0, a0, a2 4781; RV32ZICOND-NEXT: sltu a1, a5, a1 4782; RV32ZICOND-NEXT: add a0, a7, a0 4783; RV32ZICOND-NEXT: add a0, a0, a1 4784; RV32ZICOND-NEXT: xor a0, a0, a4 4785; RV32ZICOND-NEXT: xor a4, a5, a4 4786; RV32ZICOND-NEXT: or a0, a4, a0 4787; RV32ZICOND-NEXT: beqz a0, .LBB61_2 4788; RV32ZICOND-NEXT: # %bb.1: # %overflow 4789; RV32ZICOND-NEXT: li a0, 0 4790; RV32ZICOND-NEXT: ret 4791; RV32ZICOND-NEXT: .LBB61_2: # %continue 4792; RV32ZICOND-NEXT: li a0, 1 4793; RV32ZICOND-NEXT: ret 4794; 4795; RV64ZICOND-LABEL: smulo.br.i64: 4796; RV64ZICOND: # %bb.0: # %entry 4797; RV64ZICOND-NEXT: mulh a2, a0, a1 4798; RV64ZICOND-NEXT: mul a0, a0, a1 4799; RV64ZICOND-NEXT: srai a0, a0, 63 4800; RV64ZICOND-NEXT: beq a2, a0, .LBB61_2 4801; RV64ZICOND-NEXT: # %bb.1: # %overflow 4802; RV64ZICOND-NEXT: li a0, 0 4803; RV64ZICOND-NEXT: ret 4804; RV64ZICOND-NEXT: .LBB61_2: # %continue 4805; RV64ZICOND-NEXT: li a0, 1 4806; RV64ZICOND-NEXT: ret 4807entry: 4808 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2) 4809 %val = extractvalue {i64, i1} %t, 0 4810 %obit = extractvalue {i64, i1} %t, 1 4811 br i1 %obit, label %overflow, label %continue 4812 4813overflow: 4814 ret i1 false 4815 4816continue: 4817 ret i1 true 4818} 4819 4820define zeroext i1 @smulo2.br.i64(i64 %v1) { 4821; RV32-LABEL: smulo2.br.i64: 4822; RV32: # %bb.0: # %entry 4823; RV32-NEXT: li a2, -13 4824; RV32-NEXT: neg a3, a0 4825; RV32-NEXT: li a4, -1 4826; RV32-NEXT: mulhu a5, a0, a2 4827; RV32-NEXT: mul a6, a1, a2 4828; RV32-NEXT: mulhsu a2, a1, a2 4829; RV32-NEXT: add a5, a6, a5 4830; RV32-NEXT: sltu a6, a5, a6 4831; RV32-NEXT: sub a5, a5, a0 4832; RV32-NEXT: mulhsu a0, a4, a0 4833; RV32-NEXT: add a2, a2, a6 4834; RV32-NEXT: sltu a3, a5, a3 4835; RV32-NEXT: add a0, a0, a3 4836; RV32-NEXT: srai a3, a2, 31 4837; RV32-NEXT: srai a6, a0, 31 4838; RV32-NEXT: add a3, a3, a6 4839; RV32-NEXT: neg a6, a1 4840; RV32-NEXT: mulh a4, a1, a4 4841; RV32-NEXT: srai a5, a5, 31 4842; RV32-NEXT: add a0, a2, a0 4843; RV32-NEXT: sltu a2, a0, a2 4844; RV32-NEXT: sub a0, a0, a1 4845; RV32-NEXT: add a2, a3, a2 4846; RV32-NEXT: sltu a1, a0, a6 4847; RV32-NEXT: add a2, a4, a2 4848; RV32-NEXT: add a1, a2, a1 4849; RV32-NEXT: xor a1, a1, a5 4850; RV32-NEXT: xor a0, a0, a5 4851; RV32-NEXT: or a0, a0, a1 4852; RV32-NEXT: beqz a0, .LBB62_2 4853; RV32-NEXT: # %bb.1: # %overflow 4854; RV32-NEXT: li a0, 0 4855; RV32-NEXT: ret 4856; RV32-NEXT: .LBB62_2: # %continue 4857; RV32-NEXT: li a0, 1 4858; RV32-NEXT: ret 4859; 4860; RV64-LABEL: smulo2.br.i64: 4861; RV64: # %bb.0: # %entry 4862; RV64-NEXT: li a1, -13 4863; RV64-NEXT: mulh a2, a0, a1 4864; RV64-NEXT: mul a0, a0, a1 4865; RV64-NEXT: srai a0, a0, 63 4866; RV64-NEXT: beq a2, a0, .LBB62_2 4867; RV64-NEXT: # %bb.1: # %overflow 4868; RV64-NEXT: li a0, 0 4869; RV64-NEXT: ret 4870; RV64-NEXT: .LBB62_2: # %continue 4871; RV64-NEXT: li a0, 1 4872; RV64-NEXT: ret 4873; 4874; RV32ZBA-LABEL: smulo2.br.i64: 4875; RV32ZBA: # %bb.0: # %entry 4876; RV32ZBA-NEXT: li a2, -13 4877; RV32ZBA-NEXT: neg a3, a0 4878; RV32ZBA-NEXT: li a4, -1 4879; RV32ZBA-NEXT: mulhu a5, a0, a2 4880; RV32ZBA-NEXT: mul a6, a1, a2 4881; RV32ZBA-NEXT: mulhsu a2, a1, a2 4882; RV32ZBA-NEXT: add a5, a6, a5 4883; RV32ZBA-NEXT: sltu a6, a5, a6 4884; RV32ZBA-NEXT: sub a5, a5, a0 4885; RV32ZBA-NEXT: mulhsu a0, a4, a0 4886; RV32ZBA-NEXT: add a2, a2, a6 4887; RV32ZBA-NEXT: sltu a3, a5, a3 4888; RV32ZBA-NEXT: add a0, a0, a3 4889; RV32ZBA-NEXT: srai a3, a2, 31 4890; RV32ZBA-NEXT: srai a6, a0, 31 4891; RV32ZBA-NEXT: add a3, a3, a6 4892; RV32ZBA-NEXT: neg a6, a1 4893; RV32ZBA-NEXT: mulh a4, a1, a4 4894; RV32ZBA-NEXT: srai a5, a5, 31 4895; RV32ZBA-NEXT: add a0, a2, a0 4896; RV32ZBA-NEXT: sltu a2, a0, a2 4897; RV32ZBA-NEXT: sub a0, a0, a1 4898; RV32ZBA-NEXT: add a2, a3, a2 4899; RV32ZBA-NEXT: sltu a1, a0, a6 4900; RV32ZBA-NEXT: add a2, a4, a2 4901; RV32ZBA-NEXT: add a1, a2, a1 4902; RV32ZBA-NEXT: xor a1, a1, a5 4903; RV32ZBA-NEXT: xor a0, a0, a5 4904; RV32ZBA-NEXT: or a0, a0, a1 4905; RV32ZBA-NEXT: beqz a0, .LBB62_2 4906; RV32ZBA-NEXT: # %bb.1: # %overflow 4907; RV32ZBA-NEXT: li a0, 0 4908; RV32ZBA-NEXT: ret 4909; RV32ZBA-NEXT: .LBB62_2: # %continue 4910; RV32ZBA-NEXT: li a0, 1 4911; RV32ZBA-NEXT: ret 4912; 4913; RV64ZBA-LABEL: smulo2.br.i64: 4914; RV64ZBA: # %bb.0: # %entry 4915; RV64ZBA-NEXT: li a1, -13 4916; RV64ZBA-NEXT: mulh a2, a0, a1 4917; RV64ZBA-NEXT: mul a0, a0, a1 4918; RV64ZBA-NEXT: srai a0, a0, 63 4919; RV64ZBA-NEXT: beq a2, a0, .LBB62_2 4920; RV64ZBA-NEXT: # %bb.1: # %overflow 4921; RV64ZBA-NEXT: li a0, 0 4922; RV64ZBA-NEXT: ret 4923; RV64ZBA-NEXT: .LBB62_2: # %continue 4924; RV64ZBA-NEXT: li a0, 1 4925; RV64ZBA-NEXT: ret 4926; 4927; RV32ZICOND-LABEL: smulo2.br.i64: 4928; RV32ZICOND: # %bb.0: # %entry 4929; RV32ZICOND-NEXT: li a2, -13 4930; RV32ZICOND-NEXT: neg a3, a0 4931; RV32ZICOND-NEXT: li a4, -1 4932; RV32ZICOND-NEXT: mulhu a5, a0, a2 4933; RV32ZICOND-NEXT: mul a6, a1, a2 4934; RV32ZICOND-NEXT: mulhsu a2, a1, a2 4935; RV32ZICOND-NEXT: add a5, a6, a5 4936; RV32ZICOND-NEXT: sltu a6, a5, a6 4937; RV32ZICOND-NEXT: sub a5, a5, a0 4938; RV32ZICOND-NEXT: mulhsu a0, a4, a0 4939; RV32ZICOND-NEXT: add a2, a2, a6 4940; RV32ZICOND-NEXT: sltu a3, a5, a3 4941; RV32ZICOND-NEXT: add a0, a0, a3 4942; RV32ZICOND-NEXT: srai a3, a2, 31 4943; RV32ZICOND-NEXT: srai a6, a0, 31 4944; RV32ZICOND-NEXT: add a3, a3, a6 4945; RV32ZICOND-NEXT: neg a6, a1 4946; RV32ZICOND-NEXT: mulh a4, a1, a4 4947; RV32ZICOND-NEXT: srai a5, a5, 31 4948; RV32ZICOND-NEXT: add a0, a2, a0 4949; RV32ZICOND-NEXT: sltu a2, a0, a2 4950; RV32ZICOND-NEXT: sub a0, a0, a1 4951; RV32ZICOND-NEXT: add a2, a3, a2 4952; RV32ZICOND-NEXT: sltu a1, a0, a6 4953; RV32ZICOND-NEXT: add a2, a4, a2 4954; RV32ZICOND-NEXT: add a1, a2, a1 4955; RV32ZICOND-NEXT: xor a1, a1, a5 4956; RV32ZICOND-NEXT: xor a0, a0, a5 4957; RV32ZICOND-NEXT: or a0, a0, a1 4958; RV32ZICOND-NEXT: beqz a0, .LBB62_2 4959; RV32ZICOND-NEXT: # %bb.1: # %overflow 4960; RV32ZICOND-NEXT: li a0, 0 4961; RV32ZICOND-NEXT: ret 4962; RV32ZICOND-NEXT: .LBB62_2: # %continue 4963; RV32ZICOND-NEXT: li a0, 1 4964; RV32ZICOND-NEXT: ret 4965; 4966; RV64ZICOND-LABEL: smulo2.br.i64: 4967; RV64ZICOND: # %bb.0: # %entry 4968; RV64ZICOND-NEXT: li a1, -13 4969; RV64ZICOND-NEXT: mulh a2, a0, a1 4970; RV64ZICOND-NEXT: mul a0, a0, a1 4971; RV64ZICOND-NEXT: srai a0, a0, 63 4972; RV64ZICOND-NEXT: beq a2, a0, .LBB62_2 4973; RV64ZICOND-NEXT: # %bb.1: # %overflow 4974; RV64ZICOND-NEXT: li a0, 0 4975; RV64ZICOND-NEXT: ret 4976; RV64ZICOND-NEXT: .LBB62_2: # %continue 4977; RV64ZICOND-NEXT: li a0, 1 4978; RV64ZICOND-NEXT: ret 4979entry: 4980 %t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 -13) 4981 %val = extractvalue {i64, i1} %t, 0 4982 %obit = extractvalue {i64, i1} %t, 1 4983 br i1 %obit, label %overflow, label %continue 4984 4985overflow: 4986 ret i1 false 4987 4988continue: 4989 ret i1 true 4990} 4991 4992define zeroext i1 @umulo.br.i32(i32 signext %v1, i32 signext %v2) { 4993; RV32-LABEL: umulo.br.i32: 4994; RV32: # %bb.0: # %entry 4995; RV32-NEXT: mulhu a0, a0, a1 4996; RV32-NEXT: beqz a0, .LBB63_2 4997; RV32-NEXT: # %bb.1: # %overflow 4998; RV32-NEXT: li a0, 0 4999; RV32-NEXT: ret 5000; RV32-NEXT: .LBB63_2: # %continue 5001; RV32-NEXT: li a0, 1 5002; RV32-NEXT: ret 5003; 5004; RV64-LABEL: umulo.br.i32: 5005; RV64: # %bb.0: # %entry 5006; RV64-NEXT: slli a1, a1, 32 5007; RV64-NEXT: slli a0, a0, 32 5008; RV64-NEXT: mulhu a0, a0, a1 5009; RV64-NEXT: srli a0, a0, 32 5010; RV64-NEXT: beqz a0, .LBB63_2 5011; RV64-NEXT: # %bb.1: # %overflow 5012; RV64-NEXT: li a0, 0 5013; RV64-NEXT: ret 5014; RV64-NEXT: .LBB63_2: # %continue 5015; RV64-NEXT: li a0, 1 5016; RV64-NEXT: ret 5017; 5018; RV32ZBA-LABEL: umulo.br.i32: 5019; RV32ZBA: # %bb.0: # %entry 5020; RV32ZBA-NEXT: mulhu a0, a0, a1 5021; RV32ZBA-NEXT: beqz a0, .LBB63_2 5022; RV32ZBA-NEXT: # %bb.1: # %overflow 5023; RV32ZBA-NEXT: li a0, 0 5024; RV32ZBA-NEXT: ret 5025; RV32ZBA-NEXT: .LBB63_2: # %continue 5026; RV32ZBA-NEXT: li a0, 1 5027; RV32ZBA-NEXT: ret 5028; 5029; RV64ZBA-LABEL: umulo.br.i32: 5030; RV64ZBA: # %bb.0: # %entry 5031; RV64ZBA-NEXT: zext.w a1, a1 5032; RV64ZBA-NEXT: zext.w a0, a0 5033; RV64ZBA-NEXT: mul a0, a0, a1 5034; RV64ZBA-NEXT: srli a0, a0, 32 5035; RV64ZBA-NEXT: beqz a0, .LBB63_2 5036; RV64ZBA-NEXT: # %bb.1: # %overflow 5037; RV64ZBA-NEXT: li a0, 0 5038; RV64ZBA-NEXT: ret 5039; RV64ZBA-NEXT: .LBB63_2: # %continue 5040; RV64ZBA-NEXT: li a0, 1 5041; RV64ZBA-NEXT: ret 5042; 5043; RV32ZICOND-LABEL: umulo.br.i32: 5044; RV32ZICOND: # %bb.0: # %entry 5045; RV32ZICOND-NEXT: mulhu a0, a0, a1 5046; RV32ZICOND-NEXT: beqz a0, .LBB63_2 5047; RV32ZICOND-NEXT: # %bb.1: # %overflow 5048; RV32ZICOND-NEXT: li a0, 0 5049; RV32ZICOND-NEXT: ret 5050; RV32ZICOND-NEXT: .LBB63_2: # %continue 5051; RV32ZICOND-NEXT: li a0, 1 5052; RV32ZICOND-NEXT: ret 5053; 5054; RV64ZICOND-LABEL: umulo.br.i32: 5055; RV64ZICOND: # %bb.0: # %entry 5056; RV64ZICOND-NEXT: slli a1, a1, 32 5057; RV64ZICOND-NEXT: slli a0, a0, 32 5058; RV64ZICOND-NEXT: mulhu a0, a0, a1 5059; RV64ZICOND-NEXT: srli a0, a0, 32 5060; RV64ZICOND-NEXT: beqz a0, .LBB63_2 5061; RV64ZICOND-NEXT: # %bb.1: # %overflow 5062; RV64ZICOND-NEXT: li a0, 0 5063; RV64ZICOND-NEXT: ret 5064; RV64ZICOND-NEXT: .LBB63_2: # %continue 5065; RV64ZICOND-NEXT: li a0, 1 5066; RV64ZICOND-NEXT: ret 5067entry: 5068 %t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2) 5069 %val = extractvalue {i32, i1} %t, 0 5070 %obit = extractvalue {i32, i1} %t, 1 5071 br i1 %obit, label %overflow, label %continue 5072 5073overflow: 5074 ret i1 false 5075 5076continue: 5077 ret i1 true 5078} 5079 5080define zeroext i1 @umulo.br.i64(i64 %v1, i64 %v2) { 5081; RV32-LABEL: umulo.br.i64: 5082; RV32: # %bb.0: # %entry 5083; RV32-NEXT: mul a4, a3, a0 5084; RV32-NEXT: mul a5, a1, a2 5085; RV32-NEXT: mulhu a6, a0, a2 5086; RV32-NEXT: mulhu a0, a3, a0 5087; RV32-NEXT: snez a3, a3 5088; RV32-NEXT: mulhu a2, a1, a2 5089; RV32-NEXT: snez a1, a1 5090; RV32-NEXT: add a4, a5, a4 5091; RV32-NEXT: and a1, a1, a3 5092; RV32-NEXT: snez a2, a2 5093; RV32-NEXT: snez a0, a0 5094; RV32-NEXT: add a4, a6, a4 5095; RV32-NEXT: or a1, a1, a2 5096; RV32-NEXT: sltu a2, a4, a6 5097; RV32-NEXT: or a0, a1, a0 5098; RV32-NEXT: or a0, a0, a2 5099; RV32-NEXT: beqz a0, .LBB64_2 5100; RV32-NEXT: # %bb.1: # %overflow 5101; RV32-NEXT: li a0, 0 5102; RV32-NEXT: ret 5103; RV32-NEXT: .LBB64_2: # %continue 5104; RV32-NEXT: li a0, 1 5105; RV32-NEXT: ret 5106; 5107; RV64-LABEL: umulo.br.i64: 5108; RV64: # %bb.0: # %entry 5109; RV64-NEXT: mulhu a0, a0, a1 5110; RV64-NEXT: beqz a0, .LBB64_2 5111; RV64-NEXT: # %bb.1: # %overflow 5112; RV64-NEXT: li a0, 0 5113; RV64-NEXT: ret 5114; RV64-NEXT: .LBB64_2: # %continue 5115; RV64-NEXT: li a0, 1 5116; RV64-NEXT: ret 5117; 5118; RV32ZBA-LABEL: umulo.br.i64: 5119; RV32ZBA: # %bb.0: # %entry 5120; RV32ZBA-NEXT: mul a4, a3, a0 5121; RV32ZBA-NEXT: mul a5, a1, a2 5122; RV32ZBA-NEXT: mulhu a6, a0, a2 5123; RV32ZBA-NEXT: mulhu a0, a3, a0 5124; RV32ZBA-NEXT: snez a3, a3 5125; RV32ZBA-NEXT: mulhu a2, a1, a2 5126; RV32ZBA-NEXT: snez a1, a1 5127; RV32ZBA-NEXT: add a4, a5, a4 5128; RV32ZBA-NEXT: and a1, a1, a3 5129; RV32ZBA-NEXT: snez a2, a2 5130; RV32ZBA-NEXT: snez a0, a0 5131; RV32ZBA-NEXT: add a4, a6, a4 5132; RV32ZBA-NEXT: or a1, a1, a2 5133; RV32ZBA-NEXT: sltu a2, a4, a6 5134; RV32ZBA-NEXT: or a0, a1, a0 5135; RV32ZBA-NEXT: or a0, a0, a2 5136; RV32ZBA-NEXT: beqz a0, .LBB64_2 5137; RV32ZBA-NEXT: # %bb.1: # %overflow 5138; RV32ZBA-NEXT: li a0, 0 5139; RV32ZBA-NEXT: ret 5140; RV32ZBA-NEXT: .LBB64_2: # %continue 5141; RV32ZBA-NEXT: li a0, 1 5142; RV32ZBA-NEXT: ret 5143; 5144; RV64ZBA-LABEL: umulo.br.i64: 5145; RV64ZBA: # %bb.0: # %entry 5146; RV64ZBA-NEXT: mulhu a0, a0, a1 5147; RV64ZBA-NEXT: beqz a0, .LBB64_2 5148; RV64ZBA-NEXT: # %bb.1: # %overflow 5149; RV64ZBA-NEXT: li a0, 0 5150; RV64ZBA-NEXT: ret 5151; RV64ZBA-NEXT: .LBB64_2: # %continue 5152; RV64ZBA-NEXT: li a0, 1 5153; RV64ZBA-NEXT: ret 5154; 5155; RV32ZICOND-LABEL: umulo.br.i64: 5156; RV32ZICOND: # %bb.0: # %entry 5157; RV32ZICOND-NEXT: mul a4, a3, a0 5158; RV32ZICOND-NEXT: mul a5, a1, a2 5159; RV32ZICOND-NEXT: mulhu a6, a0, a2 5160; RV32ZICOND-NEXT: mulhu a0, a3, a0 5161; RV32ZICOND-NEXT: snez a3, a3 5162; RV32ZICOND-NEXT: mulhu a2, a1, a2 5163; RV32ZICOND-NEXT: snez a1, a1 5164; RV32ZICOND-NEXT: add a4, a5, a4 5165; RV32ZICOND-NEXT: and a1, a1, a3 5166; RV32ZICOND-NEXT: snez a2, a2 5167; RV32ZICOND-NEXT: snez a0, a0 5168; RV32ZICOND-NEXT: add a4, a6, a4 5169; RV32ZICOND-NEXT: or a1, a1, a2 5170; RV32ZICOND-NEXT: sltu a2, a4, a6 5171; RV32ZICOND-NEXT: or a0, a1, a0 5172; RV32ZICOND-NEXT: or a0, a0, a2 5173; RV32ZICOND-NEXT: beqz a0, .LBB64_2 5174; RV32ZICOND-NEXT: # %bb.1: # %overflow 5175; RV32ZICOND-NEXT: li a0, 0 5176; RV32ZICOND-NEXT: ret 5177; RV32ZICOND-NEXT: .LBB64_2: # %continue 5178; RV32ZICOND-NEXT: li a0, 1 5179; RV32ZICOND-NEXT: ret 5180; 5181; RV64ZICOND-LABEL: umulo.br.i64: 5182; RV64ZICOND: # %bb.0: # %entry 5183; RV64ZICOND-NEXT: mulhu a0, a0, a1 5184; RV64ZICOND-NEXT: beqz a0, .LBB64_2 5185; RV64ZICOND-NEXT: # %bb.1: # %overflow 5186; RV64ZICOND-NEXT: li a0, 0 5187; RV64ZICOND-NEXT: ret 5188; RV64ZICOND-NEXT: .LBB64_2: # %continue 5189; RV64ZICOND-NEXT: li a0, 1 5190; RV64ZICOND-NEXT: ret 5191entry: 5192 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2) 5193 %val = extractvalue {i64, i1} %t, 0 5194 %obit = extractvalue {i64, i1} %t, 1 5195 br i1 %obit, label %overflow, label %continue 5196 5197overflow: 5198 ret i1 false 5199 5200continue: 5201 ret i1 true 5202} 5203 5204define zeroext i1 @umulo2.br.i64(i64 %v1) { 5205; RV32-LABEL: umulo2.br.i64: 5206; RV32: # %bb.0: # %entry 5207; RV32-NEXT: add a2, a0, a0 5208; RV32-NEXT: sltu a0, a2, a0 5209; RV32-NEXT: add a2, a1, a1 5210; RV32-NEXT: add a2, a2, a0 5211; RV32-NEXT: beq a2, a1, .LBB65_2 5212; RV32-NEXT: # %bb.1: # %entry 5213; RV32-NEXT: sltu a0, a2, a1 5214; RV32-NEXT: .LBB65_2: # %entry 5215; RV32-NEXT: beqz a0, .LBB65_4 5216; RV32-NEXT: # %bb.3: # %overflow 5217; RV32-NEXT: li a0, 0 5218; RV32-NEXT: ret 5219; RV32-NEXT: .LBB65_4: # %continue 5220; RV32-NEXT: li a0, 1 5221; RV32-NEXT: ret 5222; 5223; RV64-LABEL: umulo2.br.i64: 5224; RV64: # %bb.0: # %entry 5225; RV64-NEXT: add a1, a0, a0 5226; RV64-NEXT: bgeu a1, a0, .LBB65_2 5227; RV64-NEXT: # %bb.1: # %overflow 5228; RV64-NEXT: li a0, 0 5229; RV64-NEXT: ret 5230; RV64-NEXT: .LBB65_2: # %continue 5231; RV64-NEXT: li a0, 1 5232; RV64-NEXT: ret 5233; 5234; RV32ZBA-LABEL: umulo2.br.i64: 5235; RV32ZBA: # %bb.0: # %entry 5236; RV32ZBA-NEXT: add a2, a0, a0 5237; RV32ZBA-NEXT: sltu a0, a2, a0 5238; RV32ZBA-NEXT: add a2, a1, a1 5239; RV32ZBA-NEXT: add a2, a2, a0 5240; RV32ZBA-NEXT: beq a2, a1, .LBB65_2 5241; RV32ZBA-NEXT: # %bb.1: # %entry 5242; RV32ZBA-NEXT: sltu a0, a2, a1 5243; RV32ZBA-NEXT: .LBB65_2: # %entry 5244; RV32ZBA-NEXT: beqz a0, .LBB65_4 5245; RV32ZBA-NEXT: # %bb.3: # %overflow 5246; RV32ZBA-NEXT: li a0, 0 5247; RV32ZBA-NEXT: ret 5248; RV32ZBA-NEXT: .LBB65_4: # %continue 5249; RV32ZBA-NEXT: li a0, 1 5250; RV32ZBA-NEXT: ret 5251; 5252; RV64ZBA-LABEL: umulo2.br.i64: 5253; RV64ZBA: # %bb.0: # %entry 5254; RV64ZBA-NEXT: add a1, a0, a0 5255; RV64ZBA-NEXT: bgeu a1, a0, .LBB65_2 5256; RV64ZBA-NEXT: # %bb.1: # %overflow 5257; RV64ZBA-NEXT: li a0, 0 5258; RV64ZBA-NEXT: ret 5259; RV64ZBA-NEXT: .LBB65_2: # %continue 5260; RV64ZBA-NEXT: li a0, 1 5261; RV64ZBA-NEXT: ret 5262; 5263; RV32ZICOND-LABEL: umulo2.br.i64: 5264; RV32ZICOND: # %bb.0: # %entry 5265; RV32ZICOND-NEXT: add a2, a0, a0 5266; RV32ZICOND-NEXT: add a3, a1, a1 5267; RV32ZICOND-NEXT: sltu a0, a2, a0 5268; RV32ZICOND-NEXT: add a3, a3, a0 5269; RV32ZICOND-NEXT: xor a2, a3, a1 5270; RV32ZICOND-NEXT: sltu a1, a3, a1 5271; RV32ZICOND-NEXT: czero.eqz a1, a1, a2 5272; RV32ZICOND-NEXT: czero.nez a0, a0, a2 5273; RV32ZICOND-NEXT: or a0, a0, a1 5274; RV32ZICOND-NEXT: beqz a0, .LBB65_2 5275; RV32ZICOND-NEXT: # %bb.1: # %overflow 5276; RV32ZICOND-NEXT: li a0, 0 5277; RV32ZICOND-NEXT: ret 5278; RV32ZICOND-NEXT: .LBB65_2: # %continue 5279; RV32ZICOND-NEXT: li a0, 1 5280; RV32ZICOND-NEXT: ret 5281; 5282; RV64ZICOND-LABEL: umulo2.br.i64: 5283; RV64ZICOND: # %bb.0: # %entry 5284; RV64ZICOND-NEXT: add a1, a0, a0 5285; RV64ZICOND-NEXT: bgeu a1, a0, .LBB65_2 5286; RV64ZICOND-NEXT: # %bb.1: # %overflow 5287; RV64ZICOND-NEXT: li a0, 0 5288; RV64ZICOND-NEXT: ret 5289; RV64ZICOND-NEXT: .LBB65_2: # %continue 5290; RV64ZICOND-NEXT: li a0, 1 5291; RV64ZICOND-NEXT: ret 5292entry: 5293 %t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 2) 5294 %val = extractvalue {i64, i1} %t, 0 5295 %obit = extractvalue {i64, i1} %t, 1 5296 br i1 %obit, label %overflow, label %continue 5297 5298overflow: 5299 ret i1 false 5300 5301continue: 5302 ret i1 true 5303} 5304 5305define zeroext i1 @uaddo.i64.constant(i64 %v1, ptr %res) { 5306; RV32-LABEL: uaddo.i64.constant: 5307; RV32: # %bb.0: # %entry 5308; RV32-NEXT: addi a3, a0, 2 5309; RV32-NEXT: sltu a0, a3, a0 5310; RV32-NEXT: add a4, a1, a0 5311; RV32-NEXT: sltu a1, a4, a1 5312; RV32-NEXT: and a0, a0, a1 5313; RV32-NEXT: sw a3, 0(a2) 5314; RV32-NEXT: sw a4, 4(a2) 5315; RV32-NEXT: ret 5316; 5317; RV64-LABEL: uaddo.i64.constant: 5318; RV64: # %bb.0: # %entry 5319; RV64-NEXT: addi a2, a0, 2 5320; RV64-NEXT: sltu a0, a2, a0 5321; RV64-NEXT: sd a2, 0(a1) 5322; RV64-NEXT: ret 5323; 5324; RV32ZBA-LABEL: uaddo.i64.constant: 5325; RV32ZBA: # %bb.0: # %entry 5326; RV32ZBA-NEXT: addi a3, a0, 2 5327; RV32ZBA-NEXT: sltu a0, a3, a0 5328; RV32ZBA-NEXT: add a4, a1, a0 5329; RV32ZBA-NEXT: sltu a1, a4, a1 5330; RV32ZBA-NEXT: and a0, a0, a1 5331; RV32ZBA-NEXT: sw a3, 0(a2) 5332; RV32ZBA-NEXT: sw a4, 4(a2) 5333; RV32ZBA-NEXT: ret 5334; 5335; RV64ZBA-LABEL: uaddo.i64.constant: 5336; RV64ZBA: # %bb.0: # %entry 5337; RV64ZBA-NEXT: addi a2, a0, 2 5338; RV64ZBA-NEXT: sltu a0, a2, a0 5339; RV64ZBA-NEXT: sd a2, 0(a1) 5340; RV64ZBA-NEXT: ret 5341; 5342; RV32ZICOND-LABEL: uaddo.i64.constant: 5343; RV32ZICOND: # %bb.0: # %entry 5344; RV32ZICOND-NEXT: addi a3, a0, 2 5345; RV32ZICOND-NEXT: sltu a0, a3, a0 5346; RV32ZICOND-NEXT: add a4, a1, a0 5347; RV32ZICOND-NEXT: sltu a1, a4, a1 5348; RV32ZICOND-NEXT: and a0, a0, a1 5349; RV32ZICOND-NEXT: sw a3, 0(a2) 5350; RV32ZICOND-NEXT: sw a4, 4(a2) 5351; RV32ZICOND-NEXT: ret 5352; 5353; RV64ZICOND-LABEL: uaddo.i64.constant: 5354; RV64ZICOND: # %bb.0: # %entry 5355; RV64ZICOND-NEXT: addi a2, a0, 2 5356; RV64ZICOND-NEXT: sltu a0, a2, a0 5357; RV64ZICOND-NEXT: sd a2, 0(a1) 5358; RV64ZICOND-NEXT: ret 5359entry: 5360 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 2) 5361 %val = extractvalue {i64, i1} %t, 0 5362 %obit = extractvalue {i64, i1} %t, 1 5363 store i64 %val, ptr %res 5364 ret i1 %obit 5365} 5366 5367define zeroext i1 @uaddo.i64.constant_2048(i64 %v1, ptr %res) { 5368; RV32-LABEL: uaddo.i64.constant_2048: 5369; RV32: # %bb.0: # %entry 5370; RV32-NEXT: addi a3, a0, 2047 5371; RV32-NEXT: addi a3, a3, 1 5372; RV32-NEXT: sltu a0, a3, a0 5373; RV32-NEXT: add a4, a1, a0 5374; RV32-NEXT: sltu a1, a4, a1 5375; RV32-NEXT: and a0, a0, a1 5376; RV32-NEXT: sw a3, 0(a2) 5377; RV32-NEXT: sw a4, 4(a2) 5378; RV32-NEXT: ret 5379; 5380; RV64-LABEL: uaddo.i64.constant_2048: 5381; RV64: # %bb.0: # %entry 5382; RV64-NEXT: addi a2, a0, 2047 5383; RV64-NEXT: addi a2, a2, 1 5384; RV64-NEXT: sltu a0, a2, a0 5385; RV64-NEXT: sd a2, 0(a1) 5386; RV64-NEXT: ret 5387; 5388; RV32ZBA-LABEL: uaddo.i64.constant_2048: 5389; RV32ZBA: # %bb.0: # %entry 5390; RV32ZBA-NEXT: addi a3, a0, 2047 5391; RV32ZBA-NEXT: addi a3, a3, 1 5392; RV32ZBA-NEXT: sltu a0, a3, a0 5393; RV32ZBA-NEXT: add a4, a1, a0 5394; RV32ZBA-NEXT: sltu a1, a4, a1 5395; RV32ZBA-NEXT: and a0, a0, a1 5396; RV32ZBA-NEXT: sw a3, 0(a2) 5397; RV32ZBA-NEXT: sw a4, 4(a2) 5398; RV32ZBA-NEXT: ret 5399; 5400; RV64ZBA-LABEL: uaddo.i64.constant_2048: 5401; RV64ZBA: # %bb.0: # %entry 5402; RV64ZBA-NEXT: addi a2, a0, 2047 5403; RV64ZBA-NEXT: addi a2, a2, 1 5404; RV64ZBA-NEXT: sltu a0, a2, a0 5405; RV64ZBA-NEXT: sd a2, 0(a1) 5406; RV64ZBA-NEXT: ret 5407; 5408; RV32ZICOND-LABEL: uaddo.i64.constant_2048: 5409; RV32ZICOND: # %bb.0: # %entry 5410; RV32ZICOND-NEXT: addi a3, a0, 2047 5411; RV32ZICOND-NEXT: addi a3, a3, 1 5412; RV32ZICOND-NEXT: sltu a0, a3, a0 5413; RV32ZICOND-NEXT: add a4, a1, a0 5414; RV32ZICOND-NEXT: sltu a1, a4, a1 5415; RV32ZICOND-NEXT: and a0, a0, a1 5416; RV32ZICOND-NEXT: sw a3, 0(a2) 5417; RV32ZICOND-NEXT: sw a4, 4(a2) 5418; RV32ZICOND-NEXT: ret 5419; 5420; RV64ZICOND-LABEL: uaddo.i64.constant_2048: 5421; RV64ZICOND: # %bb.0: # %entry 5422; RV64ZICOND-NEXT: addi a2, a0, 2047 5423; RV64ZICOND-NEXT: addi a2, a2, 1 5424; RV64ZICOND-NEXT: sltu a0, a2, a0 5425; RV64ZICOND-NEXT: sd a2, 0(a1) 5426; RV64ZICOND-NEXT: ret 5427entry: 5428 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 2048) 5429 %val = extractvalue {i64, i1} %t, 0 5430 %obit = extractvalue {i64, i1} %t, 1 5431 store i64 %val, ptr %res 5432 ret i1 %obit 5433} 5434 5435define zeroext i1 @uaddo.i64.constant_2049(i64 %v1, ptr %res) { 5436; RV32-LABEL: uaddo.i64.constant_2049: 5437; RV32: # %bb.0: # %entry 5438; RV32-NEXT: addi a3, a0, 2047 5439; RV32-NEXT: addi a3, a3, 2 5440; RV32-NEXT: sltu a0, a3, a0 5441; RV32-NEXT: add a4, a1, a0 5442; RV32-NEXT: sltu a1, a4, a1 5443; RV32-NEXT: and a0, a0, a1 5444; RV32-NEXT: sw a3, 0(a2) 5445; RV32-NEXT: sw a4, 4(a2) 5446; RV32-NEXT: ret 5447; 5448; RV64-LABEL: uaddo.i64.constant_2049: 5449; RV64: # %bb.0: # %entry 5450; RV64-NEXT: addi a2, a0, 2047 5451; RV64-NEXT: addi a2, a2, 2 5452; RV64-NEXT: sltu a0, a2, a0 5453; RV64-NEXT: sd a2, 0(a1) 5454; RV64-NEXT: ret 5455; 5456; RV32ZBA-LABEL: uaddo.i64.constant_2049: 5457; RV32ZBA: # %bb.0: # %entry 5458; RV32ZBA-NEXT: addi a3, a0, 2047 5459; RV32ZBA-NEXT: addi a3, a3, 2 5460; RV32ZBA-NEXT: sltu a0, a3, a0 5461; RV32ZBA-NEXT: add a4, a1, a0 5462; RV32ZBA-NEXT: sltu a1, a4, a1 5463; RV32ZBA-NEXT: and a0, a0, a1 5464; RV32ZBA-NEXT: sw a3, 0(a2) 5465; RV32ZBA-NEXT: sw a4, 4(a2) 5466; RV32ZBA-NEXT: ret 5467; 5468; RV64ZBA-LABEL: uaddo.i64.constant_2049: 5469; RV64ZBA: # %bb.0: # %entry 5470; RV64ZBA-NEXT: addi a2, a0, 2047 5471; RV64ZBA-NEXT: addi a2, a2, 2 5472; RV64ZBA-NEXT: sltu a0, a2, a0 5473; RV64ZBA-NEXT: sd a2, 0(a1) 5474; RV64ZBA-NEXT: ret 5475; 5476; RV32ZICOND-LABEL: uaddo.i64.constant_2049: 5477; RV32ZICOND: # %bb.0: # %entry 5478; RV32ZICOND-NEXT: addi a3, a0, 2047 5479; RV32ZICOND-NEXT: addi a3, a3, 2 5480; RV32ZICOND-NEXT: sltu a0, a3, a0 5481; RV32ZICOND-NEXT: add a4, a1, a0 5482; RV32ZICOND-NEXT: sltu a1, a4, a1 5483; RV32ZICOND-NEXT: and a0, a0, a1 5484; RV32ZICOND-NEXT: sw a3, 0(a2) 5485; RV32ZICOND-NEXT: sw a4, 4(a2) 5486; RV32ZICOND-NEXT: ret 5487; 5488; RV64ZICOND-LABEL: uaddo.i64.constant_2049: 5489; RV64ZICOND: # %bb.0: # %entry 5490; RV64ZICOND-NEXT: addi a2, a0, 2047 5491; RV64ZICOND-NEXT: addi a2, a2, 2 5492; RV64ZICOND-NEXT: sltu a0, a2, a0 5493; RV64ZICOND-NEXT: sd a2, 0(a1) 5494; RV64ZICOND-NEXT: ret 5495entry: 5496 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 2049) 5497 %val = extractvalue {i64, i1} %t, 0 5498 %obit = extractvalue {i64, i1} %t, 1 5499 store i64 %val, ptr %res 5500 ret i1 %obit 5501} 5502 5503define i64 @uaddo.i64.constant_setcc_on_overflow_flag(ptr %p) { 5504; RV32-LABEL: uaddo.i64.constant_setcc_on_overflow_flag: 5505; RV32: # %bb.0: # %entry 5506; RV32-NEXT: lw a1, 0(a0) 5507; RV32-NEXT: lw a2, 4(a0) 5508; RV32-NEXT: addi a0, a1, 2 5509; RV32-NEXT: sltu a3, a0, a1 5510; RV32-NEXT: add a1, a2, a3 5511; RV32-NEXT: sltu a2, a1, a2 5512; RV32-NEXT: and a2, a3, a2 5513; RV32-NEXT: bnez a2, .LBB69_2 5514; RV32-NEXT: # %bb.1: # %IfOverflow 5515; RV32-NEXT: li a0, 0 5516; RV32-NEXT: li a1, 0 5517; RV32-NEXT: .LBB69_2: # %IfNoOverflow 5518; RV32-NEXT: ret 5519; 5520; RV64-LABEL: uaddo.i64.constant_setcc_on_overflow_flag: 5521; RV64: # %bb.0: # %entry 5522; RV64-NEXT: ld a1, 0(a0) 5523; RV64-NEXT: addi a0, a1, 2 5524; RV64-NEXT: bltu a0, a1, .LBB69_2 5525; RV64-NEXT: # %bb.1: # %IfOverflow 5526; RV64-NEXT: li a0, 0 5527; RV64-NEXT: .LBB69_2: # %IfNoOverflow 5528; RV64-NEXT: ret 5529; 5530; RV32ZBA-LABEL: uaddo.i64.constant_setcc_on_overflow_flag: 5531; RV32ZBA: # %bb.0: # %entry 5532; RV32ZBA-NEXT: lw a1, 0(a0) 5533; RV32ZBA-NEXT: lw a2, 4(a0) 5534; RV32ZBA-NEXT: addi a0, a1, 2 5535; RV32ZBA-NEXT: sltu a3, a0, a1 5536; RV32ZBA-NEXT: add a1, a2, a3 5537; RV32ZBA-NEXT: sltu a2, a1, a2 5538; RV32ZBA-NEXT: and a2, a3, a2 5539; RV32ZBA-NEXT: bnez a2, .LBB69_2 5540; RV32ZBA-NEXT: # %bb.1: # %IfOverflow 5541; RV32ZBA-NEXT: li a0, 0 5542; RV32ZBA-NEXT: li a1, 0 5543; RV32ZBA-NEXT: .LBB69_2: # %IfNoOverflow 5544; RV32ZBA-NEXT: ret 5545; 5546; RV64ZBA-LABEL: uaddo.i64.constant_setcc_on_overflow_flag: 5547; RV64ZBA: # %bb.0: # %entry 5548; RV64ZBA-NEXT: ld a1, 0(a0) 5549; RV64ZBA-NEXT: addi a0, a1, 2 5550; RV64ZBA-NEXT: bltu a0, a1, .LBB69_2 5551; RV64ZBA-NEXT: # %bb.1: # %IfOverflow 5552; RV64ZBA-NEXT: li a0, 0 5553; RV64ZBA-NEXT: .LBB69_2: # %IfNoOverflow 5554; RV64ZBA-NEXT: ret 5555; 5556; RV32ZICOND-LABEL: uaddo.i64.constant_setcc_on_overflow_flag: 5557; RV32ZICOND: # %bb.0: # %entry 5558; RV32ZICOND-NEXT: lw a1, 0(a0) 5559; RV32ZICOND-NEXT: lw a2, 4(a0) 5560; RV32ZICOND-NEXT: addi a0, a1, 2 5561; RV32ZICOND-NEXT: sltu a3, a0, a1 5562; RV32ZICOND-NEXT: add a1, a2, a3 5563; RV32ZICOND-NEXT: sltu a2, a1, a2 5564; RV32ZICOND-NEXT: and a2, a3, a2 5565; RV32ZICOND-NEXT: bnez a2, .LBB69_2 5566; RV32ZICOND-NEXT: # %bb.1: # %IfOverflow 5567; RV32ZICOND-NEXT: li a0, 0 5568; RV32ZICOND-NEXT: li a1, 0 5569; RV32ZICOND-NEXT: .LBB69_2: # %IfNoOverflow 5570; RV32ZICOND-NEXT: ret 5571; 5572; RV64ZICOND-LABEL: uaddo.i64.constant_setcc_on_overflow_flag: 5573; RV64ZICOND: # %bb.0: # %entry 5574; RV64ZICOND-NEXT: ld a1, 0(a0) 5575; RV64ZICOND-NEXT: addi a0, a1, 2 5576; RV64ZICOND-NEXT: bltu a0, a1, .LBB69_2 5577; RV64ZICOND-NEXT: # %bb.1: # %IfOverflow 5578; RV64ZICOND-NEXT: li a0, 0 5579; RV64ZICOND-NEXT: .LBB69_2: # %IfNoOverflow 5580; RV64ZICOND-NEXT: ret 5581entry: 5582 %v1 = load i64, ptr %p 5583 %t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 2) 5584 %val = extractvalue {i64, i1} %t, 0 5585 %obit = extractvalue {i64, i1} %t, 1 5586 br i1 %obit, label %IfNoOverflow, label %IfOverflow 5587IfOverflow: 5588 ret i64 0 5589IfNoOverflow: 5590 ret i64 %val 5591} 5592 5593declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone 5594declare {i64, i1} @llvm.sadd.with.overflow.i64(i64, i64) nounwind readnone 5595declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone 5596declare {i64, i1} @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone 5597declare {i32, i1} @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone 5598declare {i64, i1} @llvm.ssub.with.overflow.i64(i64, i64) nounwind readnone 5599declare {i32, i1} @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone 5600declare {i64, i1} @llvm.usub.with.overflow.i64(i64, i64) nounwind readnone 5601declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone 5602declare {i64, i1} @llvm.smul.with.overflow.i64(i64, i64) nounwind readnone 5603declare {i32, i1} @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone 5604declare {i64, i1} @llvm.umul.with.overflow.i64(i64, i64) nounwind readnone 5605