1342 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \3; RUN: | FileCheck %s -check-prefixes=RV324; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \5; RUN: | FileCheck %s -check-prefixes=RV646 7;Copy tests from llvm/tests/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll8;to test shouldFormOverflowOp on RISCV9 10define i64 @uaddo1_overflow_used(i64 %a, i64 %b) nounwind ssp {11; RV32-LABEL: uaddo1_overflow_used:12; RV32: # %bb.0:13; RV32-NEXT: add a5, a3, a114; RV32-NEXT: add a4, a2, a015; RV32-NEXT: sltu a6, a4, a216; RV32-NEXT: add a5, a5, a617; RV32-NEXT: beq a5, a1, .LBB0_218; RV32-NEXT: # %bb.1:19; RV32-NEXT: sltu a0, a5, a120; RV32-NEXT: beqz a0, .LBB0_321; RV32-NEXT: j .LBB0_422; RV32-NEXT: .LBB0_2:23; RV32-NEXT: sltu a0, a4, a024; RV32-NEXT: bnez a0, .LBB0_425; RV32-NEXT: .LBB0_3:26; RV32-NEXT: li a2, 4227; RV32-NEXT: .LBB0_4:28; RV32-NEXT: neg a1, a029; RV32-NEXT: and a1, a1, a330; RV32-NEXT: mv a0, a231; RV32-NEXT: ret32;33; RV64-LABEL: uaddo1_overflow_used:34; RV64: # %bb.0:35; RV64-NEXT: add a2, a1, a036; RV64-NEXT: bltu a2, a0, .LBB0_237; RV64-NEXT: # %bb.1:38; RV64-NEXT: li a1, 4239; RV64-NEXT: .LBB0_2:40; RV64-NEXT: mv a0, a141; RV64-NEXT: ret42 %add = add i64 %b, %a43 %cmp = icmp ult i64 %add, %a44 %Q = select i1 %cmp, i64 %b, i64 4245 ret i64 %Q46}47 48define i64 @uaddo1_math_overflow_used(i64 %a, i64 %b, ptr %res) nounwind ssp {49; RV32-LABEL: uaddo1_math_overflow_used:50; RV32: # %bb.0:51; RV32-NEXT: add a5, a3, a152; RV32-NEXT: add a0, a2, a053; RV32-NEXT: sltu a1, a0, a254; RV32-NEXT: add a5, a5, a155; RV32-NEXT: beq a5, a3, .LBB1_256; RV32-NEXT: # %bb.1:57; RV32-NEXT: sltu a1, a5, a358; RV32-NEXT: .LBB1_2:59; RV32-NEXT: bnez a1, .LBB1_460; RV32-NEXT: # %bb.3:61; RV32-NEXT: li a2, 4262; RV32-NEXT: .LBB1_4:63; RV32-NEXT: neg a1, a164; RV32-NEXT: and a1, a1, a365; RV32-NEXT: sw a0, 0(a4)66; RV32-NEXT: sw a5, 4(a4)67; RV32-NEXT: mv a0, a268; RV32-NEXT: ret69;70; RV64-LABEL: uaddo1_math_overflow_used:71; RV64: # %bb.0:72; RV64-NEXT: add a0, a1, a073; RV64-NEXT: bltu a0, a1, .LBB1_274; RV64-NEXT: # %bb.1:75; RV64-NEXT: li a1, 4276; RV64-NEXT: .LBB1_2:77; RV64-NEXT: sd a0, 0(a2)78; RV64-NEXT: mv a0, a179; RV64-NEXT: ret80 %add = add i64 %b, %a81 %cmp = icmp ult i64 %add, %a82 %Q = select i1 %cmp, i64 %b, i64 4283 store i64 %add, ptr %res84 ret i64 %Q85}86 87define i64 @uaddo2_overflow_used(i64 %a, i64 %b) nounwind ssp {88; RV32-LABEL: uaddo2_overflow_used:89; RV32: # %bb.0:90; RV32-NEXT: add a1, a3, a191; RV32-NEXT: add a0, a2, a092; RV32-NEXT: sltu a0, a0, a293; RV32-NEXT: add a1, a1, a094; RV32-NEXT: beq a1, a3, .LBB2_295; RV32-NEXT: # %bb.1:96; RV32-NEXT: sltu a0, a1, a397; RV32-NEXT: .LBB2_2:98; RV32-NEXT: bnez a0, .LBB2_499; RV32-NEXT: # %bb.3:100; RV32-NEXT: li a2, 42101; RV32-NEXT: .LBB2_4:102; RV32-NEXT: neg a1, a0103; RV32-NEXT: and a1, a1, a3104; RV32-NEXT: mv a0, a2105; RV32-NEXT: ret106;107; RV64-LABEL: uaddo2_overflow_used:108; RV64: # %bb.0:109; RV64-NEXT: add a0, a1, a0110; RV64-NEXT: bltu a0, a1, .LBB2_2111; RV64-NEXT: # %bb.1:112; RV64-NEXT: li a1, 42113; RV64-NEXT: .LBB2_2:114; RV64-NEXT: mv a0, a1115; RV64-NEXT: ret116 %add = add i64 %b, %a117 %cmp = icmp ult i64 %add, %b118 %Q = select i1 %cmp, i64 %b, i64 42119 ret i64 %Q120}121 122define i64 @uaddo2_math_overflow_used(i64 %a, i64 %b, ptr %res) nounwind ssp {123; RV32-LABEL: uaddo2_math_overflow_used:124; RV32: # %bb.0:125; RV32-NEXT: add a5, a3, a1126; RV32-NEXT: add a0, a2, a0127; RV32-NEXT: sltu a1, a0, a2128; RV32-NEXT: add a5, a5, a1129; RV32-NEXT: beq a5, a3, .LBB3_2130; RV32-NEXT: # %bb.1:131; RV32-NEXT: sltu a1, a5, a3132; RV32-NEXT: .LBB3_2:133; RV32-NEXT: bnez a1, .LBB3_4134; RV32-NEXT: # %bb.3:135; RV32-NEXT: li a2, 42136; RV32-NEXT: .LBB3_4:137; RV32-NEXT: neg a1, a1138; RV32-NEXT: and a1, a1, a3139; RV32-NEXT: sw a0, 0(a4)140; RV32-NEXT: sw a5, 4(a4)141; RV32-NEXT: mv a0, a2142; RV32-NEXT: ret143;144; RV64-LABEL: uaddo2_math_overflow_used:145; RV64: # %bb.0:146; RV64-NEXT: add a0, a1, a0147; RV64-NEXT: bltu a0, a1, .LBB3_2148; RV64-NEXT: # %bb.1:149; RV64-NEXT: li a1, 42150; RV64-NEXT: .LBB3_2:151; RV64-NEXT: sd a0, 0(a2)152; RV64-NEXT: mv a0, a1153; RV64-NEXT: ret154 %add = add i64 %b, %a155 %cmp = icmp ult i64 %add, %b156 %Q = select i1 %cmp, i64 %b, i64 42157 store i64 %add, ptr %res158 ret i64 %Q159}160 161define i64 @uaddo3_overflow_used(i64 %a, i64 %b) nounwind ssp {162; RV32-LABEL: uaddo3_overflow_used:163; RV32: # %bb.0:164; RV32-NEXT: add a1, a3, a1165; RV32-NEXT: add a0, a2, a0166; RV32-NEXT: sltu a0, a0, a2167; RV32-NEXT: add a1, a1, a0168; RV32-NEXT: beq a3, a1, .LBB4_2169; RV32-NEXT: # %bb.1:170; RV32-NEXT: sltu a0, a1, a3171; RV32-NEXT: .LBB4_2:172; RV32-NEXT: bnez a0, .LBB4_4173; RV32-NEXT: # %bb.3:174; RV32-NEXT: li a2, 42175; RV32-NEXT: .LBB4_4:176; RV32-NEXT: neg a1, a0177; RV32-NEXT: and a1, a1, a3178; RV32-NEXT: mv a0, a2179; RV32-NEXT: ret180;181; RV64-LABEL: uaddo3_overflow_used:182; RV64: # %bb.0:183; RV64-NEXT: add a0, a1, a0184; RV64-NEXT: bltu a0, a1, .LBB4_2185; RV64-NEXT: # %bb.1:186; RV64-NEXT: li a1, 42187; RV64-NEXT: .LBB4_2:188; RV64-NEXT: mv a0, a1189; RV64-NEXT: ret190 %add = add i64 %b, %a191 %cmp = icmp ugt i64 %b, %add192 %Q = select i1 %cmp, i64 %b, i64 42193 ret i64 %Q194}195 196define i64 @uaddo3_math_overflow_used(i64 %a, i64 %b, ptr %res) nounwind ssp {197; RV32-LABEL: uaddo3_math_overflow_used:198; RV32: # %bb.0:199; RV32-NEXT: add a5, a3, a1200; RV32-NEXT: add a0, a2, a0201; RV32-NEXT: sltu a1, a0, a2202; RV32-NEXT: add a5, a5, a1203; RV32-NEXT: beq a5, a3, .LBB5_2204; RV32-NEXT: # %bb.1:205; RV32-NEXT: sltu a1, a5, a3206; RV32-NEXT: .LBB5_2:207; RV32-NEXT: bnez a1, .LBB5_4208; RV32-NEXT: # %bb.3:209; RV32-NEXT: li a2, 42210; RV32-NEXT: .LBB5_4:211; RV32-NEXT: neg a1, a1212; RV32-NEXT: and a1, a1, a3213; RV32-NEXT: sw a0, 0(a4)214; RV32-NEXT: sw a5, 4(a4)215; RV32-NEXT: mv a0, a2216; RV32-NEXT: ret217;218; RV64-LABEL: uaddo3_math_overflow_used:219; RV64: # %bb.0:220; RV64-NEXT: add a0, a1, a0221; RV64-NEXT: bltu a0, a1, .LBB5_2222; RV64-NEXT: # %bb.1:223; RV64-NEXT: li a1, 42224; RV64-NEXT: .LBB5_2:225; RV64-NEXT: sd a0, 0(a2)226; RV64-NEXT: mv a0, a1227; RV64-NEXT: ret228 %add = add i64 %b, %a229 %cmp = icmp ugt i64 %b, %add230 %Q = select i1 %cmp, i64 %b, i64 42231 store i64 %add, ptr %res232 ret i64 %Q233}234 235; Ensure CGP doesn't sink the compare before we have a chance to form the overflow intrinsic.236 237define i64 @uaddo4(i64 %a, i64 %b, i1 %c) nounwind ssp {238; RV32-LABEL: uaddo4:239; RV32: # %bb.0: # %entry240; RV32-NEXT: andi a4, a4, 1241; RV32-NEXT: beqz a4, .LBB6_6242; RV32-NEXT: # %bb.1: # %next243; RV32-NEXT: add a1, a3, a1244; RV32-NEXT: add a0, a2, a0245; RV32-NEXT: sltu a0, a0, a2246; RV32-NEXT: add a1, a1, a0247; RV32-NEXT: beq a3, a1, .LBB6_3248; RV32-NEXT: # %bb.2: # %next249; RV32-NEXT: sltu a0, a1, a3250; RV32-NEXT: .LBB6_3: # %next251; RV32-NEXT: bnez a0, .LBB6_5252; RV32-NEXT: # %bb.4: # %next253; RV32-NEXT: li a2, 42254; RV32-NEXT: .LBB6_5: # %next255; RV32-NEXT: neg a1, a0256; RV32-NEXT: and a1, a1, a3257; RV32-NEXT: mv a0, a2258; RV32-NEXT: ret259; RV32-NEXT: .LBB6_6: # %exit260; RV32-NEXT: li a0, 0261; RV32-NEXT: li a1, 0262; RV32-NEXT: ret263;264; RV64-LABEL: uaddo4:265; RV64: # %bb.0: # %entry266; RV64-NEXT: andi a2, a2, 1267; RV64-NEXT: beqz a2, .LBB6_4268; RV64-NEXT: # %bb.1: # %next269; RV64-NEXT: add a0, a1, a0270; RV64-NEXT: bltu a0, a1, .LBB6_3271; RV64-NEXT: # %bb.2: # %next272; RV64-NEXT: li a1, 42273; RV64-NEXT: .LBB6_3: # %next274; RV64-NEXT: mv a0, a1275; RV64-NEXT: ret276; RV64-NEXT: .LBB6_4: # %exit277; RV64-NEXT: li a0, 0278; RV64-NEXT: ret279entry:280 %add = add i64 %b, %a281 %cmp = icmp ugt i64 %b, %add282 br i1 %c, label %next, label %exit283 284next:285 %Q = select i1 %cmp, i64 %b, i64 42286 ret i64 %Q287 288exit:289 ret i64 0290}291 292define i64 @uaddo5(i64 %a, i64 %b, ptr %ptr, i1 %c) nounwind ssp {293; RV32-LABEL: uaddo5:294; RV32: # %bb.0: # %entry295; RV32-NEXT: andi a5, a5, 1296; RV32-NEXT: add a1, a3, a1297; RV32-NEXT: add a6, a2, a0298; RV32-NEXT: sltu a0, a6, a2299; RV32-NEXT: add a1, a1, a0300; RV32-NEXT: sw a6, 0(a4)301; RV32-NEXT: sw a1, 4(a4)302; RV32-NEXT: beqz a5, .LBB7_6303; RV32-NEXT: # %bb.1: # %next304; RV32-NEXT: beq a3, a1, .LBB7_3305; RV32-NEXT: # %bb.2: # %next306; RV32-NEXT: sltu a0, a1, a3307; RV32-NEXT: .LBB7_3: # %next308; RV32-NEXT: bnez a0, .LBB7_5309; RV32-NEXT: # %bb.4: # %next310; RV32-NEXT: li a2, 42311; RV32-NEXT: .LBB7_5: # %next312; RV32-NEXT: neg a1, a0313; RV32-NEXT: and a1, a1, a3314; RV32-NEXT: mv a0, a2315; RV32-NEXT: ret316; RV32-NEXT: .LBB7_6: # %exit317; RV32-NEXT: li a0, 0318; RV32-NEXT: li a1, 0319; RV32-NEXT: ret320;321; RV64-LABEL: uaddo5:322; RV64: # %bb.0: # %entry323; RV64-NEXT: andi a3, a3, 1324; RV64-NEXT: add a0, a1, a0325; RV64-NEXT: sd a0, 0(a2)326; RV64-NEXT: beqz a3, .LBB7_4327; RV64-NEXT: # %bb.1: # %next328; RV64-NEXT: bltu a0, a1, .LBB7_3329; RV64-NEXT: # %bb.2: # %next330; RV64-NEXT: li a1, 42331; RV64-NEXT: .LBB7_3: # %next332; RV64-NEXT: mv a0, a1333; RV64-NEXT: ret334; RV64-NEXT: .LBB7_4: # %exit335; RV64-NEXT: li a0, 0336; RV64-NEXT: ret337entry:338 %add = add i64 %b, %a339 store i64 %add, ptr %ptr340 %cmp = icmp ugt i64 %b, %add341 br i1 %c, label %next, label %exit342 343next:344 %Q = select i1 %cmp, i64 %b, i64 42345 ret i64 %Q346 347exit:348 ret i64 0349}350 351; Instcombine folds (a + b <u a) to (a ^ -1 <u b). Make sure we match this352; pattern as well.353define i64 @uaddo6_xor(i64 %a, i64 %b) {354; RV32-LABEL: uaddo6_xor:355; RV32: # %bb.0:356; RV32-NEXT: not a1, a1357; RV32-NEXT: beq a1, a3, .LBB8_2358; RV32-NEXT: # %bb.1:359; RV32-NEXT: sltu a0, a1, a3360; RV32-NEXT: beqz a0, .LBB8_3361; RV32-NEXT: j .LBB8_4362; RV32-NEXT: .LBB8_2:363; RV32-NEXT: not a0, a0364; RV32-NEXT: sltu a0, a0, a2365; RV32-NEXT: bnez a0, .LBB8_4366; RV32-NEXT: .LBB8_3:367; RV32-NEXT: li a2, 42368; RV32-NEXT: .LBB8_4:369; RV32-NEXT: neg a1, a0370; RV32-NEXT: and a1, a1, a3371; RV32-NEXT: mv a0, a2372; RV32-NEXT: ret373;374; RV64-LABEL: uaddo6_xor:375; RV64: # %bb.0:376; RV64-NEXT: not a2, a0377; RV64-NEXT: mv a0, a1378; RV64-NEXT: bltu a2, a1, .LBB8_2379; RV64-NEXT: # %bb.1:380; RV64-NEXT: li a0, 42381; RV64-NEXT: .LBB8_2:382; RV64-NEXT: ret383 %x = xor i64 %a, -1384 %cmp = icmp ult i64 %x, %b385 %Q = select i1 %cmp, i64 %b, i64 42386 ret i64 %Q387}388 389define i64 @uaddo6_xor_commuted(i64 %a, i64 %b) {390; RV32-LABEL: uaddo6_xor_commuted:391; RV32: # %bb.0:392; RV32-NEXT: not a1, a1393; RV32-NEXT: beq a1, a3, .LBB9_2394; RV32-NEXT: # %bb.1:395; RV32-NEXT: sltu a0, a1, a3396; RV32-NEXT: beqz a0, .LBB9_3397; RV32-NEXT: j .LBB9_4398; RV32-NEXT: .LBB9_2:399; RV32-NEXT: not a0, a0400; RV32-NEXT: sltu a0, a0, a2401; RV32-NEXT: bnez a0, .LBB9_4402; RV32-NEXT: .LBB9_3:403; RV32-NEXT: li a2, 42404; RV32-NEXT: .LBB9_4:405; RV32-NEXT: neg a1, a0406; RV32-NEXT: and a1, a1, a3407; RV32-NEXT: mv a0, a2408; RV32-NEXT: ret409;410; RV64-LABEL: uaddo6_xor_commuted:411; RV64: # %bb.0:412; RV64-NEXT: not a2, a0413; RV64-NEXT: mv a0, a1414; RV64-NEXT: bltu a2, a1, .LBB9_2415; RV64-NEXT: # %bb.1:416; RV64-NEXT: li a0, 42417; RV64-NEXT: .LBB9_2:418; RV64-NEXT: ret419 %x = xor i64 %a, -1420 %cmp = icmp ult i64 %x, %b421 %Q = select i1 %cmp, i64 %b, i64 42422 ret i64 %Q423}424 425declare void @use(i64)426 427define i64 @uaddo6_xor_multi_use(i64 %a, i64 %b) {428; RV32-LABEL: uaddo6_xor_multi_use:429; RV32: # %bb.0:430; RV32-NEXT: addi sp, sp, -16431; RV32-NEXT: .cfi_def_cfa_offset 16432; RV32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill433; RV32-NEXT: sw s0, 8(sp) # 4-byte Folded Spill434; RV32-NEXT: sw s1, 4(sp) # 4-byte Folded Spill435; RV32-NEXT: .cfi_offset ra, -4436; RV32-NEXT: .cfi_offset s0, -8437; RV32-NEXT: .cfi_offset s1, -12438; RV32-NEXT: mv s0, a2439; RV32-NEXT: not a1, a1440; RV32-NEXT: not a0, a0441; RV32-NEXT: beq a1, a3, .LBB10_2442; RV32-NEXT: # %bb.1:443; RV32-NEXT: sltu a2, a1, a3444; RV32-NEXT: beqz a2, .LBB10_3445; RV32-NEXT: j .LBB10_4446; RV32-NEXT: .LBB10_2:447; RV32-NEXT: sltu a2, a0, s0448; RV32-NEXT: bnez a2, .LBB10_4449; RV32-NEXT: .LBB10_3:450; RV32-NEXT: li s0, 42451; RV32-NEXT: .LBB10_4:452; RV32-NEXT: neg s1, a2453; RV32-NEXT: and s1, s1, a3454; RV32-NEXT: call use455; RV32-NEXT: mv a0, s0456; RV32-NEXT: mv a1, s1457; RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload458; RV32-NEXT: lw s0, 8(sp) # 4-byte Folded Reload459; RV32-NEXT: lw s1, 4(sp) # 4-byte Folded Reload460; RV32-NEXT: .cfi_restore ra461; RV32-NEXT: .cfi_restore s0462; RV32-NEXT: .cfi_restore s1463; RV32-NEXT: addi sp, sp, 16464; RV32-NEXT: .cfi_def_cfa_offset 0465; RV32-NEXT: ret466;467; RV64-LABEL: uaddo6_xor_multi_use:468; RV64: # %bb.0:469; RV64-NEXT: addi sp, sp, -16470; RV64-NEXT: .cfi_def_cfa_offset 16471; RV64-NEXT: sd ra, 8(sp) # 8-byte Folded Spill472; RV64-NEXT: sd s0, 0(sp) # 8-byte Folded Spill473; RV64-NEXT: .cfi_offset ra, -8474; RV64-NEXT: .cfi_offset s0, -16475; RV64-NEXT: not a0, a0476; RV64-NEXT: mv s0, a1477; RV64-NEXT: bltu a0, a1, .LBB10_2478; RV64-NEXT: # %bb.1:479; RV64-NEXT: li s0, 42480; RV64-NEXT: .LBB10_2:481; RV64-NEXT: call use482; RV64-NEXT: mv a0, s0483; RV64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload484; RV64-NEXT: ld s0, 0(sp) # 8-byte Folded Reload485; RV64-NEXT: .cfi_restore ra486; RV64-NEXT: .cfi_restore s0487; RV64-NEXT: addi sp, sp, 16488; RV64-NEXT: .cfi_def_cfa_offset 0489; RV64-NEXT: ret490 %x = xor i64 -1, %a491 %cmp = icmp ult i64 %x, %b492 %Q = select i1 %cmp, i64 %b, i64 42493 call void @use(i64 %x)494 ret i64 %Q495}496 497; Make sure we do not use the XOR binary operator as insert point, as it may498; come before the second operand of the overflow intrinsic.499define i1 @uaddo6_xor_op_after_XOR(i32 %a, ptr %b.ptr) {500; RV32-LABEL: uaddo6_xor_op_after_XOR:501; RV32: # %bb.0:502; RV32-NEXT: lw a1, 0(a1)503; RV32-NEXT: not a0, a0504; RV32-NEXT: sltu a0, a0, a1505; RV32-NEXT: xori a0, a0, 1506; RV32-NEXT: ret507;508; RV64-LABEL: uaddo6_xor_op_after_XOR:509; RV64: # %bb.0:510; RV64-NEXT: lw a1, 0(a1)511; RV64-NEXT: not a0, a0512; RV64-NEXT: sext.w a0, a0513; RV64-NEXT: sltu a0, a0, a1514; RV64-NEXT: xori a0, a0, 1515; RV64-NEXT: ret516 %x = xor i32 %a, -1517 %b = load i32, ptr %b.ptr, align 8518 %cmp14 = icmp ugt i32 %b, %x519 %ov = xor i1 %cmp14, true520 ret i1 %ov521}522 523; When adding 1, the general pattern for add-overflow may be different due to icmp canonicalization.524; PR31754: https://bugs.llvm.org/show_bug.cgi?id=31754525 526define i1 @uaddo_i64_increment(i64 %x, ptr %p) {527; RV32-LABEL: uaddo_i64_increment:528; RV32: # %bb.0:529; RV32-NEXT: addi a3, a0, 1530; RV32-NEXT: seqz a0, a3531; RV32-NEXT: add a1, a1, a0532; RV32-NEXT: or a0, a3, a1533; RV32-NEXT: seqz a0, a0534; RV32-NEXT: sw a3, 0(a2)535; RV32-NEXT: sw a1, 4(a2)536; RV32-NEXT: ret537;538; RV64-LABEL: uaddo_i64_increment:539; RV64: # %bb.0:540; RV64-NEXT: addi a2, a0, 1541; RV64-NEXT: seqz a0, a2542; RV64-NEXT: sd a2, 0(a1)543; RV64-NEXT: ret544 %a = add i64 %x, 1545 %ov = icmp eq i64 %a, 0546 store i64 %a, ptr %p547 ret i1 %ov548}549 550define i1 @uaddo_i8_increment_noncanonical_1(i8 %x, ptr %p) {551; RV32-LABEL: uaddo_i8_increment_noncanonical_1:552; RV32: # %bb.0:553; RV32-NEXT: addi a2, a0, 1554; RV32-NEXT: zext.b a0, a2555; RV32-NEXT: seqz a0, a0556; RV32-NEXT: sb a2, 0(a1)557; RV32-NEXT: ret558;559; RV64-LABEL: uaddo_i8_increment_noncanonical_1:560; RV64: # %bb.0:561; RV64-NEXT: addi a2, a0, 1562; RV64-NEXT: zext.b a0, a2563; RV64-NEXT: seqz a0, a0564; RV64-NEXT: sb a2, 0(a1)565; RV64-NEXT: ret566 %a = add i8 1, %x ; commute567 %ov = icmp eq i8 %a, 0568 store i8 %a, ptr %p569 ret i1 %ov570}571 572define i1 @uaddo_i32_increment_noncanonical_2(i32 %x, ptr %p) {573; RV32-LABEL: uaddo_i32_increment_noncanonical_2:574; RV32: # %bb.0:575; RV32-NEXT: addi a2, a0, 1576; RV32-NEXT: seqz a0, a2577; RV32-NEXT: sw a2, 0(a1)578; RV32-NEXT: ret579;580; RV64-LABEL: uaddo_i32_increment_noncanonical_2:581; RV64: # %bb.0:582; RV64-NEXT: addiw a2, a0, 1583; RV64-NEXT: seqz a0, a2584; RV64-NEXT: sw a2, 0(a1)585; RV64-NEXT: ret586 %a = add i32 %x, 1587 %ov = icmp eq i32 0, %a ; commute588 store i32 %a, ptr %p589 ret i1 %ov590}591 592define i1 @uaddo_i16_increment_noncanonical_3(i16 %x, ptr %p) {593; RV32-LABEL: uaddo_i16_increment_noncanonical_3:594; RV32: # %bb.0:595; RV32-NEXT: addi a2, a0, 1596; RV32-NEXT: slli a0, a2, 16597; RV32-NEXT: seqz a0, a0598; RV32-NEXT: sh a2, 0(a1)599; RV32-NEXT: ret600;601; RV64-LABEL: uaddo_i16_increment_noncanonical_3:602; RV64: # %bb.0:603; RV64-NEXT: addi a2, a0, 1604; RV64-NEXT: slli a0, a2, 48605; RV64-NEXT: seqz a0, a0606; RV64-NEXT: sh a2, 0(a1)607; RV64-NEXT: ret608 %a = add i16 1, %x ; commute609 %ov = icmp eq i16 0, %a ; commute610 store i16 %a, ptr %p611 ret i1 %ov612}613 614; The overflow check may be against the input rather than the sum.615 616define i1 @uaddo_i64_increment_alt(i64 %x, ptr %p) {617; RV32-LABEL: uaddo_i64_increment_alt:618; RV32: # %bb.0:619; RV32-NEXT: addi a3, a0, 1620; RV32-NEXT: seqz a0, a3621; RV32-NEXT: add a1, a1, a0622; RV32-NEXT: or a0, a3, a1623; RV32-NEXT: seqz a0, a0624; RV32-NEXT: sw a3, 0(a2)625; RV32-NEXT: sw a1, 4(a2)626; RV32-NEXT: ret627;628; RV64-LABEL: uaddo_i64_increment_alt:629; RV64: # %bb.0:630; RV64-NEXT: addi a2, a0, 1631; RV64-NEXT: seqz a0, a2632; RV64-NEXT: sd a2, 0(a1)633; RV64-NEXT: ret634 %a = add i64 %x, 1635 store i64 %a, ptr %p636 %ov = icmp eq i64 %x, -1637 ret i1 %ov638}639 640; Make sure insertion is done correctly based on dominance.641 642define i1 @uaddo_i64_increment_alt_dom(i64 %x, ptr %p) {643; RV32-LABEL: uaddo_i64_increment_alt_dom:644; RV32: # %bb.0:645; RV32-NEXT: addi a3, a0, 1646; RV32-NEXT: seqz a0, a3647; RV32-NEXT: add a1, a1, a0648; RV32-NEXT: or a0, a3, a1649; RV32-NEXT: seqz a0, a0650; RV32-NEXT: sw a3, 0(a2)651; RV32-NEXT: sw a1, 4(a2)652; RV32-NEXT: ret653;654; RV64-LABEL: uaddo_i64_increment_alt_dom:655; RV64: # %bb.0:656; RV64-NEXT: addi a2, a0, 1657; RV64-NEXT: seqz a0, a2658; RV64-NEXT: sd a2, 0(a1)659; RV64-NEXT: ret660 %ov = icmp eq i64 %x, -1661 %a = add i64 %x, 1662 store i64 %a, ptr %p663 ret i1 %ov664}665 666; The overflow check may be against the input rather than the sum.667 668define i1 @uaddo_i32_decrement_alt(i32 signext %x, ptr %p) {669; RV32-LABEL: uaddo_i32_decrement_alt:670; RV32: # %bb.0:671; RV32-NEXT: snez a2, a0672; RV32-NEXT: addi a0, a0, -1673; RV32-NEXT: sw a0, 0(a1)674; RV32-NEXT: mv a0, a2675; RV32-NEXT: ret676;677; RV64-LABEL: uaddo_i32_decrement_alt:678; RV64: # %bb.0:679; RV64-NEXT: snez a2, a0680; RV64-NEXT: addi a0, a0, -1681; RV64-NEXT: sw a0, 0(a1)682; RV64-NEXT: mv a0, a2683; RV64-NEXT: ret684 %a = add i32 %x, -1685 store i32 %a, ptr %p686 %ov = icmp ne i32 %x, 0687 ret i1 %ov688}689 690define i1 @uaddo_i64_decrement_alt(i64 %x, ptr %p) {691; RV32-LABEL: uaddo_i64_decrement_alt:692; RV32: # %bb.0:693; RV32-NEXT: or a3, a0, a1694; RV32-NEXT: seqz a4, a0695; RV32-NEXT: addi a5, a0, -1696; RV32-NEXT: snez a0, a3697; RV32-NEXT: sub a1, a1, a4698; RV32-NEXT: sw a5, 0(a2)699; RV32-NEXT: sw a1, 4(a2)700; RV32-NEXT: ret701;702; RV64-LABEL: uaddo_i64_decrement_alt:703; RV64: # %bb.0:704; RV64-NEXT: snez a2, a0705; RV64-NEXT: addi a0, a0, -1706; RV64-NEXT: sd a0, 0(a1)707; RV64-NEXT: mv a0, a2708; RV64-NEXT: ret709 %a = add i64 %x, -1710 store i64 %a, ptr %p711 %ov = icmp ne i64 %x, 0712 ret i1 %ov713}714 715; Make sure insertion is done correctly based on dominance.716 717define i1 @uaddo_i64_decrement_alt_dom(i64 %x, ptr %p) {718; RV32-LABEL: uaddo_i64_decrement_alt_dom:719; RV32: # %bb.0:720; RV32-NEXT: or a3, a0, a1721; RV32-NEXT: seqz a4, a0722; RV32-NEXT: addi a5, a0, -1723; RV32-NEXT: snez a0, a3724; RV32-NEXT: sub a1, a1, a4725; RV32-NEXT: sw a5, 0(a2)726; RV32-NEXT: sw a1, 4(a2)727; RV32-NEXT: ret728;729; RV64-LABEL: uaddo_i64_decrement_alt_dom:730; RV64: # %bb.0:731; RV64-NEXT: snez a2, a0732; RV64-NEXT: addi a0, a0, -1733; RV64-NEXT: sd a0, 0(a1)734; RV64-NEXT: mv a0, a2735; RV64-NEXT: ret736 %ov = icmp ne i64 %x, 0737 %a = add i64 %x, -1738 store i64 %a, ptr %p739 ret i1 %ov740}741 742; No transform for illegal types.743 744define i1 @uaddo_i42_increment_illegal_type(i42 %x, ptr %p) {745; RV32-LABEL: uaddo_i42_increment_illegal_type:746; RV32: # %bb.0:747; RV32-NEXT: addi a3, a0, 1748; RV32-NEXT: seqz a0, a3749; RV32-NEXT: add a0, a1, a0750; RV32-NEXT: andi a1, a0, 1023751; RV32-NEXT: or a0, a3, a1752; RV32-NEXT: seqz a0, a0753; RV32-NEXT: sw a3, 0(a2)754; RV32-NEXT: sh a1, 4(a2)755; RV32-NEXT: ret756;757; RV64-LABEL: uaddo_i42_increment_illegal_type:758; RV64: # %bb.0:759; RV64-NEXT: addi a2, a0, 1760; RV64-NEXT: slli a3, a2, 22761; RV64-NEXT: seqz a0, a3762; RV64-NEXT: srli a3, a3, 54763; RV64-NEXT: sw a2, 0(a1)764; RV64-NEXT: sh a3, 4(a1)765; RV64-NEXT: ret766 %a = add i42 %x, 1767 %ov = icmp eq i42 %a, 0768 store i42 %a, ptr %p769 ret i1 %ov770}771 772define i1 @usubo_ult_i64_overflow_used(i64 %x, i64 %y, ptr %p) {773; RV32-LABEL: usubo_ult_i64_overflow_used:774; RV32: # %bb.0:775; RV32-NEXT: beq a1, a3, .LBB22_2776; RV32-NEXT: # %bb.1:777; RV32-NEXT: sltu a0, a1, a3778; RV32-NEXT: ret779; RV32-NEXT: .LBB22_2:780; RV32-NEXT: sltu a0, a0, a2781; RV32-NEXT: ret782;783; RV64-LABEL: usubo_ult_i64_overflow_used:784; RV64: # %bb.0:785; RV64-NEXT: sltu a0, a0, a1786; RV64-NEXT: ret787 %s = sub i64 %x, %y788 %ov = icmp ult i64 %x, %y789 ret i1 %ov790}791 792define i1 @usubo_ult_i64_math_overflow_used(i64 %x, i64 %y, ptr %p) {793; RV32-LABEL: usubo_ult_i64_math_overflow_used:794; RV32: # %bb.0:795; RV32-NEXT: mv a5, a0796; RV32-NEXT: sltu a0, a0, a2797; RV32-NEXT: sub a6, a1, a3798; RV32-NEXT: sub a5, a5, a2799; RV32-NEXT: sub a2, a6, a0800; RV32-NEXT: sw a5, 0(a4)801; RV32-NEXT: sw a2, 4(a4)802; RV32-NEXT: beq a1, a3, .LBB23_2803; RV32-NEXT: # %bb.1:804; RV32-NEXT: sltu a0, a1, a3805; RV32-NEXT: .LBB23_2:806; RV32-NEXT: ret807;808; RV64-LABEL: usubo_ult_i64_math_overflow_used:809; RV64: # %bb.0:810; RV64-NEXT: sub a3, a0, a1811; RV64-NEXT: sltu a0, a0, a1812; RV64-NEXT: sd a3, 0(a2)813; RV64-NEXT: ret814 %s = sub i64 %x, %y815 store i64 %s, ptr %p816 %ov = icmp ult i64 %x, %y817 ret i1 %ov818}819 820; Verify insertion point for single-BB. Toggle predicate.821 822define i1 @usubo_ugt_i32(i32 %x, i32 %y, ptr %p) {823; RV32-LABEL: usubo_ugt_i32:824; RV32: # %bb.0:825; RV32-NEXT: sltu a3, a0, a1826; RV32-NEXT: sub a0, a0, a1827; RV32-NEXT: sw a0, 0(a2)828; RV32-NEXT: mv a0, a3829; RV32-NEXT: ret830;831; RV64-LABEL: usubo_ugt_i32:832; RV64: # %bb.0:833; RV64-NEXT: sext.w a3, a1834; RV64-NEXT: sext.w a4, a0835; RV64-NEXT: sltu a3, a4, a3836; RV64-NEXT: sub a0, a0, a1837; RV64-NEXT: sw a0, 0(a2)838; RV64-NEXT: mv a0, a3839; RV64-NEXT: ret840 %ov = icmp ugt i32 %y, %x841 %s = sub i32 %x, %y842 store i32 %s, ptr %p843 ret i1 %ov844}845 846; Constant operand should match.847 848define i1 @usubo_ugt_constant_op0_i8(i8 %x, ptr %p) {849; RV32-LABEL: usubo_ugt_constant_op0_i8:850; RV32: # %bb.0:851; RV32-NEXT: zext.b a2, a0852; RV32-NEXT: li a3, 42853; RV32-NEXT: sub a3, a3, a0854; RV32-NEXT: sltiu a0, a2, 43855; RV32-NEXT: xori a0, a0, 1856; RV32-NEXT: sb a3, 0(a1)857; RV32-NEXT: ret858;859; RV64-LABEL: usubo_ugt_constant_op0_i8:860; RV64: # %bb.0:861; RV64-NEXT: zext.b a2, a0862; RV64-NEXT: li a3, 42863; RV64-NEXT: sub a3, a3, a0864; RV64-NEXT: sltiu a0, a2, 43865; RV64-NEXT: xori a0, a0, 1866; RV64-NEXT: sb a3, 0(a1)867; RV64-NEXT: ret868 %s = sub i8 42, %x869 %ov = icmp ugt i8 %x, 42870 store i8 %s, ptr %p871 ret i1 %ov872}873 874; Compare with constant operand 0 is canonicalized by commuting, but verify match for non-canonical form.875 876define i1 @usubo_ult_constant_op0_i16(i16 %x, ptr %p) {877; RV32-LABEL: usubo_ult_constant_op0_i16:878; RV32: # %bb.0:879; RV32-NEXT: slli a2, a0, 16880; RV32-NEXT: li a3, 43881; RV32-NEXT: srli a2, a2, 16882; RV32-NEXT: sub a3, a3, a0883; RV32-NEXT: sltiu a0, a2, 44884; RV32-NEXT: xori a0, a0, 1885; RV32-NEXT: sh a3, 0(a1)886; RV32-NEXT: ret887;888; RV64-LABEL: usubo_ult_constant_op0_i16:889; RV64: # %bb.0:890; RV64-NEXT: slli a2, a0, 48891; RV64-NEXT: li a3, 43892; RV64-NEXT: srli a2, a2, 48893; RV64-NEXT: sub a3, a3, a0894; RV64-NEXT: sltiu a0, a2, 44895; RV64-NEXT: xori a0, a0, 1896; RV64-NEXT: sh a3, 0(a1)897; RV64-NEXT: ret898 %s = sub i16 43, %x899 %ov = icmp ult i16 43, %x900 store i16 %s, ptr %p901 ret i1 %ov902}903 904; Subtract with constant operand 1 is canonicalized to add.905 906define i1 @usubo_ult_constant_op1_i16(i16 %x, ptr %p) {907; RV32-LABEL: usubo_ult_constant_op1_i16:908; RV32: # %bb.0:909; RV32-NEXT: slli a2, a0, 16910; RV32-NEXT: srli a2, a2, 16911; RV32-NEXT: addi a3, a0, -44912; RV32-NEXT: sltiu a0, a2, 44913; RV32-NEXT: sh a3, 0(a1)914; RV32-NEXT: ret915;916; RV64-LABEL: usubo_ult_constant_op1_i16:917; RV64: # %bb.0:918; RV64-NEXT: slli a2, a0, 48919; RV64-NEXT: srli a2, a2, 48920; RV64-NEXT: addi a3, a0, -44921; RV64-NEXT: sltiu a0, a2, 44922; RV64-NEXT: sh a3, 0(a1)923; RV64-NEXT: ret924 %s = add i16 %x, -44925 %ov = icmp ult i16 %x, 44926 store i16 %s, ptr %p927 ret i1 %ov928}929 930define i1 @usubo_ugt_constant_op1_i8(i8 %x, ptr %p) {931; RV32-LABEL: usubo_ugt_constant_op1_i8:932; RV32: # %bb.0:933; RV32-NEXT: zext.b a2, a0934; RV32-NEXT: sltiu a2, a2, 45935; RV32-NEXT: addi a0, a0, -45936; RV32-NEXT: sb a0, 0(a1)937; RV32-NEXT: mv a0, a2938; RV32-NEXT: ret939;940; RV64-LABEL: usubo_ugt_constant_op1_i8:941; RV64: # %bb.0:942; RV64-NEXT: zext.b a2, a0943; RV64-NEXT: sltiu a2, a2, 45944; RV64-NEXT: addi a0, a0, -45945; RV64-NEXT: sb a0, 0(a1)946; RV64-NEXT: mv a0, a2947; RV64-NEXT: ret948 %ov = icmp ugt i8 45, %x949 %s = add i8 %x, -45950 store i8 %s, ptr %p951 ret i1 %ov952}953 954; Special-case: subtract 1 changes the compare predicate and constant.955 956define i1 @usubo_eq_constant1_op1_i32(i32 %x, ptr %p) {957; RV32-LABEL: usubo_eq_constant1_op1_i32:958; RV32: # %bb.0:959; RV32-NEXT: addi a2, a0, -1960; RV32-NEXT: seqz a0, a0961; RV32-NEXT: sw a2, 0(a1)962; RV32-NEXT: ret963;964; RV64-LABEL: usubo_eq_constant1_op1_i32:965; RV64: # %bb.0:966; RV64-NEXT: sext.w a2, a0967; RV64-NEXT: addi a3, a0, -1968; RV64-NEXT: seqz a0, a2969; RV64-NEXT: sw a3, 0(a1)970; RV64-NEXT: ret971 %s = add i32 %x, -1972 %ov = icmp eq i32 %x, 0973 store i32 %s, ptr %p974 ret i1 %ov975}976 977; Special-case: subtract from 0 (negate) changes the compare predicate.978 979define i1 @usubo_ne_constant0_op1_i32(i32 %x, ptr %p) {980; RV32-LABEL: usubo_ne_constant0_op1_i32:981; RV32: # %bb.0:982; RV32-NEXT: neg a2, a0983; RV32-NEXT: snez a0, a0984; RV32-NEXT: sw a2, 0(a1)985; RV32-NEXT: ret986;987; RV64-LABEL: usubo_ne_constant0_op1_i32:988; RV64: # %bb.0:989; RV64-NEXT: sext.w a2, a0990; RV64-NEXT: neg a3, a0991; RV64-NEXT: snez a0, a2992; RV64-NEXT: sw a3, 0(a1)993; RV64-NEXT: ret994 %s = sub i32 0, %x995 %ov = icmp ne i32 %x, 0996 store i32 %s, ptr %p997 ret i1 %ov998}999 1000; This used to verify insertion point for multi-BB, but now we just bail out.1001 1002declare void @call(i1)1003 1004define i1 @usubo_ult_sub_dominates_i64(i64 %x, i64 %y, ptr %p, i1 %cond) {1005; RV32-LABEL: usubo_ult_sub_dominates_i64:1006; RV32: # %bb.0: # %entry1007; RV32-NEXT: andi a6, a5, 11008; RV32-NEXT: beqz a6, .LBB31_51009; RV32-NEXT: # %bb.1: # %t1010; RV32-NEXT: mv a7, a01011; RV32-NEXT: sltu a0, a0, a21012; RV32-NEXT: sub t0, a1, a31013; RV32-NEXT: sub a2, a7, a21014; RV32-NEXT: sub a7, t0, a01015; RV32-NEXT: sw a2, 0(a4)1016; RV32-NEXT: sw a7, 4(a4)1017; RV32-NEXT: beqz a6, .LBB31_51018; RV32-NEXT: # %bb.2: # %end1019; RV32-NEXT: beq a1, a3, .LBB31_41020; RV32-NEXT: # %bb.3: # %end1021; RV32-NEXT: sltu a0, a1, a31022; RV32-NEXT: .LBB31_4: # %end1023; RV32-NEXT: ret1024; RV32-NEXT: .LBB31_5: # %f1025; RV32-NEXT: mv a0, a51026; RV32-NEXT: ret1027;1028; RV64-LABEL: usubo_ult_sub_dominates_i64:1029; RV64: # %bb.0: # %entry1030; RV64-NEXT: andi a4, a3, 11031; RV64-NEXT: beqz a4, .LBB31_31032; RV64-NEXT: # %bb.1: # %t1033; RV64-NEXT: sub a5, a0, a11034; RV64-NEXT: sd a5, 0(a2)1035; RV64-NEXT: beqz a4, .LBB31_31036; RV64-NEXT: # %bb.2: # %end1037; RV64-NEXT: sltu a0, a0, a11038; RV64-NEXT: ret1039; RV64-NEXT: .LBB31_3: # %f1040; RV64-NEXT: mv a0, a31041; RV64-NEXT: ret1042entry:1043 br i1 %cond, label %t, label %f1044 1045t:1046 %s = sub i64 %x, %y1047 store i64 %s, ptr %p1048 br i1 %cond, label %end, label %f1049 1050f:1051 ret i1 %cond1052 1053end:1054 %ov = icmp ult i64 %x, %y1055 ret i1 %ov1056}1057 1058define i1 @usubo_ult_cmp_dominates_i64(i64 %x, i64 %y, ptr %p, i1 %cond) {1059; RV32-LABEL: usubo_ult_cmp_dominates_i64:1060; RV32: # %bb.0: # %entry1061; RV32-NEXT: addi sp, sp, -321062; RV32-NEXT: .cfi_def_cfa_offset 321063; RV32-NEXT: sw ra, 28(sp) # 4-byte Folded Spill1064; RV32-NEXT: sw s0, 24(sp) # 4-byte Folded Spill1065; RV32-NEXT: sw s1, 20(sp) # 4-byte Folded Spill1066; RV32-NEXT: sw s2, 16(sp) # 4-byte Folded Spill1067; RV32-NEXT: sw s3, 12(sp) # 4-byte Folded Spill1068; RV32-NEXT: sw s4, 8(sp) # 4-byte Folded Spill1069; RV32-NEXT: sw s5, 4(sp) # 4-byte Folded Spill1070; RV32-NEXT: sw s6, 0(sp) # 4-byte Folded Spill1071; RV32-NEXT: .cfi_offset ra, -41072; RV32-NEXT: .cfi_offset s0, -81073; RV32-NEXT: .cfi_offset s1, -121074; RV32-NEXT: .cfi_offset s2, -161075; RV32-NEXT: .cfi_offset s3, -201076; RV32-NEXT: .cfi_offset s4, -241077; RV32-NEXT: .cfi_offset s5, -281078; RV32-NEXT: .cfi_offset s6, -321079; RV32-NEXT: mv s1, a51080; RV32-NEXT: mv s4, a11081; RV32-NEXT: andi a1, a5, 11082; RV32-NEXT: beqz a1, .LBB32_61083; RV32-NEXT: # %bb.1: # %t1084; RV32-NEXT: mv s0, a41085; RV32-NEXT: mv s3, a31086; RV32-NEXT: mv s2, a21087; RV32-NEXT: mv s5, a01088; RV32-NEXT: beq s4, a3, .LBB32_31089; RV32-NEXT: # %bb.2: # %t1090; RV32-NEXT: sltu s6, s4, s31091; RV32-NEXT: j .LBB32_41092; RV32-NEXT: .LBB32_3:1093; RV32-NEXT: sltu s6, s5, s21094; RV32-NEXT: .LBB32_4: # %t1095; RV32-NEXT: mv a0, s61096; RV32-NEXT: call call1097; RV32-NEXT: beqz s6, .LBB32_61098; RV32-NEXT: # %bb.5: # %end1099; RV32-NEXT: sltu a0, s5, s21100; RV32-NEXT: sub a1, s4, s31101; RV32-NEXT: sub a2, s5, s21102; RV32-NEXT: sub a1, a1, a01103; RV32-NEXT: sw a2, 0(s0)1104; RV32-NEXT: sw a1, 4(s0)1105; RV32-NEXT: mv a0, s61106; RV32-NEXT: j .LBB32_71107; RV32-NEXT: .LBB32_6: # %f1108; RV32-NEXT: mv a0, s11109; RV32-NEXT: .LBB32_7: # %f1110; RV32-NEXT: lw ra, 28(sp) # 4-byte Folded Reload1111; RV32-NEXT: lw s0, 24(sp) # 4-byte Folded Reload1112; RV32-NEXT: lw s1, 20(sp) # 4-byte Folded Reload1113; RV32-NEXT: lw s2, 16(sp) # 4-byte Folded Reload1114; RV32-NEXT: lw s3, 12(sp) # 4-byte Folded Reload1115; RV32-NEXT: lw s4, 8(sp) # 4-byte Folded Reload1116; RV32-NEXT: lw s5, 4(sp) # 4-byte Folded Reload1117; RV32-NEXT: lw s6, 0(sp) # 4-byte Folded Reload1118; RV32-NEXT: .cfi_restore ra1119; RV32-NEXT: .cfi_restore s01120; RV32-NEXT: .cfi_restore s11121; RV32-NEXT: .cfi_restore s21122; RV32-NEXT: .cfi_restore s31123; RV32-NEXT: .cfi_restore s41124; RV32-NEXT: .cfi_restore s51125; RV32-NEXT: .cfi_restore s61126; RV32-NEXT: addi sp, sp, 321127; RV32-NEXT: .cfi_def_cfa_offset 01128; RV32-NEXT: ret1129;1130; RV64-LABEL: usubo_ult_cmp_dominates_i64:1131; RV64: # %bb.0: # %entry1132; RV64-NEXT: addi sp, sp, -481133; RV64-NEXT: .cfi_def_cfa_offset 481134; RV64-NEXT: sd ra, 40(sp) # 8-byte Folded Spill1135; RV64-NEXT: sd s0, 32(sp) # 8-byte Folded Spill1136; RV64-NEXT: sd s1, 24(sp) # 8-byte Folded Spill1137; RV64-NEXT: sd s2, 16(sp) # 8-byte Folded Spill1138; RV64-NEXT: sd s3, 8(sp) # 8-byte Folded Spill1139; RV64-NEXT: sd s4, 0(sp) # 8-byte Folded Spill1140; RV64-NEXT: .cfi_offset ra, -81141; RV64-NEXT: .cfi_offset s0, -161142; RV64-NEXT: .cfi_offset s1, -241143; RV64-NEXT: .cfi_offset s2, -321144; RV64-NEXT: .cfi_offset s3, -401145; RV64-NEXT: .cfi_offset s4, -481146; RV64-NEXT: mv s0, a31147; RV64-NEXT: mv s2, a11148; RV64-NEXT: andi a1, a3, 11149; RV64-NEXT: beqz a1, .LBB32_31150; RV64-NEXT: # %bb.1: # %t1151; RV64-NEXT: mv s1, a21152; RV64-NEXT: mv s3, a01153; RV64-NEXT: sltu s4, a0, s21154; RV64-NEXT: mv a0, s41155; RV64-NEXT: call call1156; RV64-NEXT: bgeu s3, s2, .LBB32_31157; RV64-NEXT: # %bb.2: # %end1158; RV64-NEXT: sub a0, s3, s21159; RV64-NEXT: sd a0, 0(s1)1160; RV64-NEXT: mv a0, s41161; RV64-NEXT: j .LBB32_41162; RV64-NEXT: .LBB32_3: # %f1163; RV64-NEXT: mv a0, s01164; RV64-NEXT: .LBB32_4: # %f1165; RV64-NEXT: ld ra, 40(sp) # 8-byte Folded Reload1166; RV64-NEXT: ld s0, 32(sp) # 8-byte Folded Reload1167; RV64-NEXT: ld s1, 24(sp) # 8-byte Folded Reload1168; RV64-NEXT: ld s2, 16(sp) # 8-byte Folded Reload1169; RV64-NEXT: ld s3, 8(sp) # 8-byte Folded Reload1170; RV64-NEXT: ld s4, 0(sp) # 8-byte Folded Reload1171; RV64-NEXT: .cfi_restore ra1172; RV64-NEXT: .cfi_restore s01173; RV64-NEXT: .cfi_restore s11174; RV64-NEXT: .cfi_restore s21175; RV64-NEXT: .cfi_restore s31176; RV64-NEXT: .cfi_restore s41177; RV64-NEXT: addi sp, sp, 481178; RV64-NEXT: .cfi_def_cfa_offset 01179; RV64-NEXT: ret1180entry:1181 br i1 %cond, label %t, label %f1182 1183t:1184 %ov = icmp ult i64 %x, %y1185 call void @call(i1 %ov)1186 br i1 %ov, label %end, label %f1187 1188f:1189 ret i1 %cond1190 1191end:1192 %s = sub i64 %x, %y1193 store i64 %s, ptr %p1194 ret i1 %ov1195}1196 1197; Verify that crazy/non-canonical code does not crash.1198 1199define void @bar() {1200; RV32-LABEL: bar:1201; RV32: # %bb.0:1202;1203; RV64-LABEL: bar:1204; RV64: # %bb.0:1205 %cmp = icmp eq i64 1, -11206 %frombool = zext i1 %cmp to i81207 unreachable1208}1209 1210define void @foo() {1211; RV32-LABEL: foo:1212; RV32: # %bb.0:1213;1214; RV64-LABEL: foo:1215; RV64: # %bb.0:1216 %sub = add nsw i64 1, 11217 %conv = trunc i64 %sub to i321218 unreachable1219}1220 1221; Similarly for usubo.1222 1223define i1 @bar2() {1224; RV32-LABEL: bar2:1225; RV32: # %bb.0:1226; RV32-NEXT: li a0, 01227; RV32-NEXT: ret1228;1229; RV64-LABEL: bar2:1230; RV64: # %bb.0:1231; RV64-NEXT: li a0, 01232; RV64-NEXT: ret1233 %cmp = icmp eq i64 1, 01234 ret i1 %cmp1235}1236 1237define i64 @foo2(ptr %p) {1238; RV32-LABEL: foo2:1239; RV32: # %bb.0:1240; RV32-NEXT: li a0, 01241; RV32-NEXT: li a1, 01242; RV32-NEXT: ret1243;1244; RV64-LABEL: foo2:1245; RV64: # %bb.0:1246; RV64-NEXT: li a0, 01247; RV64-NEXT: ret1248 %sub = add nsw i64 1, -11249 ret i64 %sub1250}1251 1252; Avoid hoisting a math op into a dominating block which would1253; increase the critical path.1254 1255define void @PR41129(ptr %p64) {1256; RV32-LABEL: PR41129:1257; RV32: # %bb.0: # %entry1258; RV32-NEXT: lw a1, 0(a0)1259; RV32-NEXT: lw a2, 4(a0)1260; RV32-NEXT: or a3, a1, a21261; RV32-NEXT: beqz a3, .LBB37_21262; RV32-NEXT: # %bb.1: # %false1263; RV32-NEXT: andi a1, a1, 71264; RV32-NEXT: sw a1, 0(a0)1265; RV32-NEXT: sw zero, 4(a0)1266; RV32-NEXT: ret1267; RV32-NEXT: .LBB37_2: # %true1268; RV32-NEXT: seqz a3, a11269; RV32-NEXT: addi a1, a1, -11270; RV32-NEXT: sub a2, a2, a31271; RV32-NEXT: sw a1, 0(a0)1272; RV32-NEXT: sw a2, 4(a0)1273; RV32-NEXT: ret1274;1275; RV64-LABEL: PR41129:1276; RV64: # %bb.0: # %entry1277; RV64-NEXT: ld a1, 0(a0)1278; RV64-NEXT: beqz a1, .LBB37_21279; RV64-NEXT: # %bb.1: # %false1280; RV64-NEXT: andi a1, a1, 71281; RV64-NEXT: sd a1, 0(a0)1282; RV64-NEXT: ret1283; RV64-NEXT: .LBB37_2: # %true1284; RV64-NEXT: addi a1, a1, -11285; RV64-NEXT: sd a1, 0(a0)1286; RV64-NEXT: ret1287entry:1288 %key = load i64, ptr %p64, align 81289 %cond17 = icmp eq i64 %key, 01290 br i1 %cond17, label %true, label %false1291 1292false:1293 %andval = and i64 %key, 71294 store i64 %andval, ptr %p641295 br label %exit1296 1297true:1298 %svalue = add i64 %key, -11299 store i64 %svalue, ptr %p641300 br label %exit1301 1302exit:1303 ret void1304}1305 1306define i16 @overflow_not_used(i16 %a, i16 %b, ptr %res) {1307; RV32-LABEL: overflow_not_used:1308; RV32: # %bb.0:1309; RV32-NEXT: lui a3, 161310; RV32-NEXT: add a0, a1, a01311; RV32-NEXT: addi a3, a3, -11312; RV32-NEXT: and a4, a1, a31313; RV32-NEXT: and a3, a0, a31314; RV32-NEXT: bltu a3, a4, .LBB38_21315; RV32-NEXT: # %bb.1:1316; RV32-NEXT: li a1, 421317; RV32-NEXT: .LBB38_2:1318; RV32-NEXT: sh a0, 0(a2)1319; RV32-NEXT: mv a0, a11320; RV32-NEXT: ret1321;1322; RV64-LABEL: overflow_not_used:1323; RV64: # %bb.0:1324; RV64-NEXT: lui a3, 161325; RV64-NEXT: add a0, a1, a01326; RV64-NEXT: addi a3, a3, -11327; RV64-NEXT: and a4, a1, a31328; RV64-NEXT: and a3, a0, a31329; RV64-NEXT: bltu a3, a4, .LBB38_21330; RV64-NEXT: # %bb.1:1331; RV64-NEXT: li a1, 421332; RV64-NEXT: .LBB38_2:1333; RV64-NEXT: sh a0, 0(a2)1334; RV64-NEXT: mv a0, a11335; RV64-NEXT: ret1336 %add = add i16 %b, %a1337 %cmp = icmp ult i16 %add, %b1338 %Q = select i1 %cmp, i16 %b, i16 421339 store i16 %add, ptr %res1340 ret i16 %Q1341}1342