1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --include-generated-funcs --version 2 2; RUN: llc -mtriple=riscv64 -riscv-enable-copy-propagation -enable-machine-outliner -verify-machineinstrs < %s \ 3; RUN: | FileCheck %s -check-prefix=RV64I 4 5; The outlined function produced by this test case contains a register to 6; register copy, which is at risk of being removed by MachineCopyPropagation 7; if it can't see that the copy is used. At the time of writing this test 8; case, MCP will remove the copy if it is run after the machine outliner. 9 10define signext i32 @nge(i32 signext %a, i32 signext %b) nounwind { 11entry: 12 %cmp = icmp sge i32 %a, %b 13 %conv.neg = sext i1 %cmp to i32 14 ret i32 %conv.neg 15} 16 17define signext i32 @ngt(i32 signext %a, i32 signext %b) nounwind { 18entry: 19 %cmp = icmp sgt i32 %a, %b 20 %conv.neg = sext i1 %cmp to i32 21 ret i32 %conv.neg 22} 23 24define signext i32 @nle(i32 signext %a, i32 signext %b) nounwind { 25entry: 26 %cmp = icmp sle i32 %a, %b 27 %conv.neg = sext i1 %cmp to i32 28 ret i32 %conv.neg 29} 30 31define signext i32 @nlt(i32 signext %a, i32 signext %b) nounwind { 32entry: 33 %cmp = icmp slt i32 %a, %b 34 %conv.neg = sext i1 %cmp to i32 35 ret i32 %conv.neg 36} 37 38define signext i32 @main() nounwind { 39entry: 40 %call = tail call signext i32 @nge(i32 signext -2147483648, i32 signext 2147483647) 41 %cmp.not = icmp eq i32 %call, 0 42 br i1 %cmp.not, label %if.end, label %if.then 43 44if.then: 45 tail call void @abort() 46 unreachable 47 48if.end: 49 %call1 = tail call signext i32 @nge(i32 signext 2147483647, i32 signext -2147483648) 50 %cmp2.not = icmp eq i32 %call1, -1 51 br i1 %cmp2.not, label %if.end4, label %if.then3 52 53if.then3: 54 tail call void @abort() 55 unreachable 56 57if.end4: 58 %call5 = tail call signext i32 @ngt(i32 signext -2147483648, i32 signext 2147483647) 59 %cmp6.not = icmp eq i32 %call5, 0 60 br i1 %cmp6.not, label %if.end8, label %if.then7 61 62if.then7: 63 tail call void @abort() 64 unreachable 65 66if.end8: 67 %call9 = tail call signext i32 @ngt(i32 signext 2147483647, i32 signext -2147483648) 68 %cmp10.not = icmp eq i32 %call9, -1 69 br i1 %cmp10.not, label %if.end12, label %if.then11 70 71if.then11: 72 tail call void @abort() 73 unreachable 74 75if.end12: 76 %call13 = tail call signext i32 @nle(i32 signext -2147483648, i32 signext 2147483647) 77 %cmp14.not = icmp eq i32 %call13, -1 78 br i1 %cmp14.not, label %if.end16, label %if.then15 79 80if.then15: 81 tail call void @abort() 82 unreachable 83 84if.end16: 85 %call17 = tail call signext i32 @nle(i32 signext 2147483647, i32 signext -2147483648) 86 %cmp18.not = icmp eq i32 %call17, 0 87 br i1 %cmp18.not, label %if.end20, label %if.then19 88 89if.then19: 90 tail call void @abort() 91 unreachable 92 93if.end20: 94 %call21 = tail call signext i32 @nlt(i32 signext -2147483648, i32 signext 2147483647) 95 %cmp22.not = icmp eq i32 %call21, -1 96 br i1 %cmp22.not, label %if.end24, label %if.then23 97 98if.then23: 99 tail call void @abort() 100 unreachable 101 102if.end24: 103 %call25 = tail call signext i32 @nlt(i32 signext 2147483647, i32 signext -2147483648) 104 %cmp26.not = icmp eq i32 %call25, 0 105 br i1 %cmp26.not, label %if.end28, label %if.then27 106 107if.then27: 108 tail call void @abort() 109 unreachable 110 111if.end28: 112 tail call void @exit(i32 signext 0) 113 unreachable 114} 115 116declare void @abort() noreturn 117declare void @exit(i32 signext) noreturn 118 119; RV64I-LABEL: nge: 120; RV64I: # %bb.0: # %entry 121; RV64I-NEXT: slt a0, a0, a1 122; RV64I-NEXT: addi a0, a0, -1 123; RV64I-NEXT: ret 124; 125; RV64I-LABEL: ngt: 126; RV64I: # %bb.0: # %entry 127; RV64I-NEXT: slt a0, a1, a0 128; RV64I-NEXT: neg a0, a0 129; RV64I-NEXT: ret 130; 131; RV64I-LABEL: nle: 132; RV64I: # %bb.0: # %entry 133; RV64I-NEXT: slt a0, a1, a0 134; RV64I-NEXT: addi a0, a0, -1 135; RV64I-NEXT: ret 136; 137; RV64I-LABEL: nlt: 138; RV64I: # %bb.0: # %entry 139; RV64I-NEXT: slt a0, a0, a1 140; RV64I-NEXT: neg a0, a0 141; RV64I-NEXT: ret 142; 143; RV64I-LABEL: main: 144; RV64I: # %bb.0: # %entry 145; RV64I-NEXT: addi sp, sp, -32 146; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill 147; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill 148; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill 149; RV64I-NEXT: call t0, OUTLINED_FUNCTION_0 150; RV64I-NEXT: call nge 151; RV64I-NEXT: bnez a0, .LBB4_9 152; RV64I-NEXT: # %bb.1: # %if.end 153; RV64I-NEXT: lui a1, 524288 154; RV64I-NEXT: mv a0, s0 155; RV64I-NEXT: call nge 156; RV64I-NEXT: li a1, -1 157; RV64I-NEXT: bne a0, a1, .LBB4_9 158; RV64I-NEXT: # %bb.2: # %if.end4 159; RV64I-NEXT: call t0, OUTLINED_FUNCTION_0 160; RV64I-NEXT: call ngt 161; RV64I-NEXT: bnez a0, .LBB4_9 162; RV64I-NEXT: # %bb.3: # %if.end8 163; RV64I-NEXT: lui a1, 524288 164; RV64I-NEXT: mv a0, s0 165; RV64I-NEXT: call ngt 166; RV64I-NEXT: li s1, -1 167; RV64I-NEXT: bne a0, s1, .LBB4_9 168; RV64I-NEXT: # %bb.4: # %if.end12 169; RV64I-NEXT: call t0, OUTLINED_FUNCTION_0 170; RV64I-NEXT: call nle 171; RV64I-NEXT: bne a0, s1, .LBB4_9 172; RV64I-NEXT: # %bb.5: # %if.end16 173; RV64I-NEXT: lui a1, 524288 174; RV64I-NEXT: mv a0, s0 175; RV64I-NEXT: call nle 176; RV64I-NEXT: bnez a0, .LBB4_9 177; RV64I-NEXT: # %bb.6: # %if.end20 178; RV64I-NEXT: call t0, OUTLINED_FUNCTION_0 179; RV64I-NEXT: call nlt 180; RV64I-NEXT: li a1, -1 181; RV64I-NEXT: bne a0, a1, .LBB4_9 182; RV64I-NEXT: # %bb.7: # %if.end24 183; RV64I-NEXT: lui a1, 524288 184; RV64I-NEXT: mv a0, s0 185; RV64I-NEXT: call nlt 186; RV64I-NEXT: bnez a0, .LBB4_9 187; RV64I-NEXT: # %bb.8: # %if.end28 188; RV64I-NEXT: call exit 189; RV64I-NEXT: .LBB4_9: # %if.then 190; RV64I-NEXT: call abort 191; 192; RV64I-LABEL: OUTLINED_FUNCTION_0: 193; RV64I: # %bb.0: 194; RV64I-NEXT: lui s0, 524288 195; RV64I-NEXT: addiw s0, s0, -1 196; RV64I-NEXT: lui a0, 524288 197; RV64I-NEXT: mv a1, s0 198; RV64I-NEXT: jr t0 199