brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.3 KiB · 881c974 Raw
412 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s3 4; If nothing is known we can't change anything5define i8 @ucmp_0(i32 %x, i32 %y) {6; CHECK-LABEL: @ucmp_0(7; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X:%.*]], i32 [[Y:%.*]])8; CHECK-NEXT:    ret i8 [[TMP1]]9;10  %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)11  ret i8 %112}13 14define i8 @scmp_0(i32 %x, i32 %y) {15; CHECK-LABEL: @scmp_0(16; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X:%.*]], i32 [[Y:%.*]])17; CHECK-NEXT:    ret i8 [[TMP1]]18;19  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)20  ret i8 %121}22 23; If we know that range of LHS < range of RHS then return -124define i8 @ucmp_1(i32 %x, i32 %y) {25  ; X is within [4, 8)26; CHECK-LABEL: @ucmp_1(27; CHECK-NEXT:    [[COND1:%.*]] = icmp samesign uge i32 [[X:%.*]], 428; CHECK-NEXT:    call void @llvm.assume(i1 [[COND1]])29; CHECK-NEXT:    [[COND2:%.*]] = icmp ult i32 [[X]], 830; CHECK-NEXT:    call void @llvm.assume(i1 [[COND2]])31; CHECK-NEXT:    [[COND3:%.*]] = icmp uge i32 [[Y:%.*]], 832; CHECK-NEXT:    call void @llvm.assume(i1 [[COND3]])33; CHECK-NEXT:    ret i8 -134;35  %cond1 = icmp uge i32 %x, 436  call void @llvm.assume(i1 %cond1)37  %cond2 = icmp ult i32 %x, 838  call void @llvm.assume(i1 %cond2)39  ; Y is within [8, UNSIGNED_MAX)40  %cond3 = icmp uge i32 %y, 841  call void @llvm.assume(i1 %cond3)42 43  %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)44  ret i8 %145}46 47define i8 @scmp_1(i32 %x, i32 %y) {48  ; X is within [-5, 3)49; CHECK-LABEL: @scmp_1(50; CHECK-NEXT:    [[COND1:%.*]] = icmp sge i32 [[X:%.*]], -551; CHECK-NEXT:    call void @llvm.assume(i1 [[COND1]])52; CHECK-NEXT:    [[COND2:%.*]] = icmp slt i32 [[X]], 353; CHECK-NEXT:    call void @llvm.assume(i1 [[COND2]])54; CHECK-NEXT:    [[COND3:%.*]] = icmp sge i32 [[Y:%.*]], 355; CHECK-NEXT:    call void @llvm.assume(i1 [[COND3]])56; CHECK-NEXT:    ret i8 -157;58  %cond1 = icmp sge i32 %x, -559  call void @llvm.assume(i1 %cond1)60  %cond2 = icmp slt i32 %x, 361  call void @llvm.assume(i1 %cond2)62  ; Y is within [3, SIGNED_MAX)63  %cond3 = icmp sge i32 %y, 364  call void @llvm.assume(i1 %cond3)65 66  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)67  ret i8 %168}69 70; If we know that range of LHS > range of RHS then return 171define i8 @ucmp_2(i32 %x, i32 %y) {72  ; X is within [4, UNSIGNED_MAX)73; CHECK-LABEL: @ucmp_2(74; CHECK-NEXT:    [[COND1:%.*]] = icmp uge i32 [[X:%.*]], 475; CHECK-NEXT:    call void @llvm.assume(i1 [[COND1]])76; CHECK-NEXT:    [[COND2:%.*]] = icmp ult i32 [[Y:%.*]], 477; CHECK-NEXT:    call void @llvm.assume(i1 [[COND2]])78; CHECK-NEXT:    ret i8 179;80  %cond1 = icmp uge i32 %x, 481  call void @llvm.assume(i1 %cond1)82  ; Y is within [0, 4)83  %cond2 = icmp ult i32 %y, 484  call void @llvm.assume(i1 %cond2)85 86  %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)87  ret i8 %188}89 90define i8 @scmp_2(i32 %x, i32 %y) {91  ; X is within [4, SIGNED_MAX)92; CHECK-LABEL: @scmp_2(93; CHECK-NEXT:    [[COND1:%.*]] = icmp sge i32 [[X:%.*]], 494; CHECK-NEXT:    call void @llvm.assume(i1 [[COND1]])95; CHECK-NEXT:    [[COND2:%.*]] = icmp slt i32 [[Y:%.*]], 496; CHECK-NEXT:    call void @llvm.assume(i1 [[COND2]])97; CHECK-NEXT:    ret i8 198;99  %cond1 = icmp sge i32 %x, 4100  call void @llvm.assume(i1 %cond1)101  ; Y is within [SIGNED_MIN, 4)102  %cond2 = icmp slt i32 %y, 4103  call void @llvm.assume(i1 %cond2)104 105  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)106  ret i8 %1107}108 109; If we know that LHS and RHS are both constants then return 0110define i8 @ucmp_5(i32 %x, i32 %y) {111; CHECK-LABEL: @ucmp_5(112; CHECK-NEXT:    [[COND1:%.*]] = icmp eq i32 [[X:%.*]], 4113; CHECK-NEXT:    call void @llvm.assume(i1 [[COND1]])114; CHECK-NEXT:    [[COND2:%.*]] = icmp eq i32 [[Y:%.*]], 4115; CHECK-NEXT:    call void @llvm.assume(i1 [[COND2]])116; CHECK-NEXT:    ret i8 0117;118  %cond1 = icmp eq i32 %x, 4119  call void @llvm.assume(i1 %cond1)120  %cond2 = icmp eq i32 %y, 4121  call void @llvm.assume(i1 %cond2)122 123  %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)124  ret i8 %1125}126 127define i8 @scmp_5(i32 %x, i32 %y) {128; CHECK-LABEL: @scmp_5(129; CHECK-NEXT:    [[COND1:%.*]] = icmp eq i32 [[X:%.*]], -5130; CHECK-NEXT:    call void @llvm.assume(i1 [[COND1]])131; CHECK-NEXT:    [[COND2:%.*]] = icmp eq i32 [[Y:%.*]], -5132; CHECK-NEXT:    call void @llvm.assume(i1 [[COND2]])133; CHECK-NEXT:    ret i8 0134;135  %cond1 = icmp eq i32 %x, -5136  call void @llvm.assume(i1 %cond1)137  %cond2 = icmp eq i32 %y, -5138  call void @llvm.assume(i1 %cond2)139 140  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)141  ret i8 %1142}143 144; We can infer ranges based on the location where a UCMP/SCMP result is used145define i8 @scmp_6(i32 noundef %x) {146; CHECK-LABEL: @scmp_6(147; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 10148; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i8 -1, i8 5149; CHECK-NEXT:    ret i8 [[TMP2]]150;151  %1 = icmp slt i32 %x, 10152  %2 = call i8 @llvm.scmp(i32 %x, i32 10)153  %3 = select i1 %1, i8 %2, i8 5154  ret i8 %3155}156 157; Negative test: ranges overlap158define i8 @ucmp_3(i32 %x, i32 %y) {159  ; X is within [4, UNSIGNED_MAX)160; CHECK-LABEL: @ucmp_3(161; CHECK-NEXT:    [[COND1:%.*]] = icmp uge i32 [[X:%.*]], 4162; CHECK-NEXT:    call void @llvm.assume(i1 [[COND1]])163; CHECK-NEXT:    [[COND2:%.*]] = icmp ult i32 [[Y:%.*]], 6164; CHECK-NEXT:    call void @llvm.assume(i1 [[COND2]])165; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])166; CHECK-NEXT:    ret i8 [[TMP1]]167;168  %cond1 = icmp uge i32 %x, 4169  call void @llvm.assume(i1 %cond1)170  ; Y is within [0, 6)171  %cond2 = icmp ult i32 %y, 6172  call void @llvm.assume(i1 %cond2)173 174  %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)175  ret i8 %1176}177 178define i8 @scmp_3(i32 %x, i32 %y) {179  ; X is within [2, SIGNED_MAX)180; CHECK-LABEL: @scmp_3(181; CHECK-NEXT:    [[COND1:%.*]] = icmp sge i32 [[X:%.*]], 2182; CHECK-NEXT:    call void @llvm.assume(i1 [[COND1]])183; CHECK-NEXT:    [[COND2:%.*]] = icmp slt i32 [[Y:%.*]], 4184; CHECK-NEXT:    call void @llvm.assume(i1 [[COND2]])185; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])186; CHECK-NEXT:    ret i8 [[TMP1]]187;188  %cond1 = icmp sge i32 %x, 2189  call void @llvm.assume(i1 %cond1)190  ; Y is within [SIGNED_MIN, 4)191  %cond2 = icmp slt i32 %y, 4192  call void @llvm.assume(i1 %cond2)193 194  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)195  ret i8 %1196}197 198; Negative test: mismatched signedness of range-establishing comparisons and199;                of the intrinsic200define i8 @ucmp_4(i32 %x, i32 %y) {201  ; X is within [4, SIGNED_MAX)202; CHECK-LABEL: @ucmp_4(203; CHECK-NEXT:    [[COND1:%.*]] = icmp sge i32 [[X:%.*]], 4204; CHECK-NEXT:    call void @llvm.assume(i1 [[COND1]])205; CHECK-NEXT:    [[COND2:%.*]] = icmp slt i32 [[Y:%.*]], 4206; CHECK-NEXT:    call void @llvm.assume(i1 [[COND2]])207; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])208; CHECK-NEXT:    ret i8 [[TMP1]]209;210  %cond1 = icmp sge i32 %x, 4211  call void @llvm.assume(i1 %cond1)212  ; Y is within [0, 4)213  %cond2 = icmp slt i32 %y, 4214  call void @llvm.assume(i1 %cond2)215 216  %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)217  ret i8 %1218}219 220define i8 @scmp_4(i32 %x, i32 %y) {221  ; X is within [4, UNSIGNED_MAX)222; CHECK-LABEL: @scmp_4(223; CHECK-NEXT:    [[COND1:%.*]] = icmp uge i32 [[X:%.*]], 4224; CHECK-NEXT:    call void @llvm.assume(i1 [[COND1]])225; CHECK-NEXT:    [[COND2:%.*]] = icmp ult i32 [[Y:%.*]], 4226; CHECK-NEXT:    call void @llvm.assume(i1 [[COND2]])227; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])228; CHECK-NEXT:    ret i8 [[TMP1]]229;230  %cond1 = icmp uge i32 %x, 4231  call void @llvm.assume(i1 %cond1)232  ; Y is within [0, 4)233  %cond2 = icmp ult i32 %y, 4234  call void @llvm.assume(i1 %cond2)235 236  %1 = call i8 @llvm.scmp(i32 %x, i32 %y)237  ret i8 %1238}239 240; Negative test: ranges are the same, but we can't be sure the values are equal241define i8 @ucmp_6(i32 %x, i32 %y) {242  ; Both X and Y are within [0, 10]243; CHECK-LABEL: @ucmp_6(244; CHECK-NEXT:    [[COND1:%.*]] = icmp ule i32 [[X:%.*]], 10245; CHECK-NEXT:    call void @llvm.assume(i1 [[COND1]])246; CHECK-NEXT:    [[COND2:%.*]] = icmp ule i32 [[Y:%.*]], 10247; CHECK-NEXT:    call void @llvm.assume(i1 [[COND2]])248; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])249; CHECK-NEXT:    ret i8 [[TMP1]]250;251  %cond1 = icmp ule i32 %x, 10252  call void @llvm.assume(i1 %cond1)253  %cond2 = icmp ule i32 %y, 10254  call void @llvm.assume(i1 %cond2)255 256  %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)257  ret i8 %1258}259 260define i8 @ucmp_switch(i32 %x, i32 %y) {261; CHECK-LABEL: @ucmp_switch(262; CHECK-NEXT:    [[CMP:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X:%.*]], i32 [[Y:%.*]])263; CHECK-NEXT:    switch i8 [[CMP]], label [[DEFAULT_UNREACHABLE:%.*]] [264; CHECK-NEXT:      i8 1, label [[BB_1:%.*]]265; CHECK-NEXT:      i8 -1, label [[BB_NEG1:%.*]]266; CHECK-NEXT:      i8 0, label [[BB_0:%.*]]267; CHECK-NEXT:    ]268; CHECK:       bb.neg2:269; CHECK-NEXT:    ret i8 -2270; CHECK:       bb.neg1:271; CHECK-NEXT:    ret i8 -1272; CHECK:       bb.0:273; CHECK-NEXT:    ret i8 0274; CHECK:       bb.1:275; CHECK-NEXT:    ret i8 1276; CHECK:       bb.2:277; CHECK-NEXT:    ret i8 2278; CHECK:       default.unreachable:279; CHECK-NEXT:    unreachable280; CHECK:       default:281; CHECK-NEXT:    ret i8 123282;283  %cmp = call i8 @llvm.ucmp(i32 %x, i32 %y)284  switch i8 %cmp, label %default [285  i8 -2, label %bb.neg2286  i8 -1, label %bb.neg1287  i8 0, label %bb.0288  i8 1, label %bb.1289  i8 2, label %bb.2290  ]291 292bb.neg2:293  ret i8 -2294 295bb.neg1:296  ret i8 -1297 298bb.0:299  ret i8 0300 301bb.1:302  ret i8 1303 304bb.2:305  ret i8 2306 307default:308  ret i8 123309}310 311define i8 @ucmp_switch_callsite_range(i32 %x, i32 %y) {312; CHECK-LABEL: @ucmp_switch_callsite_range(313; CHECK-NEXT:    [[CMP:%.*]] = call range(i8 -2, 3) i8 @llvm.ucmp.i8.i32(i32 [[X:%.*]], i32 [[Y:%.*]])314; CHECK-NEXT:    switch i8 [[CMP]], label [[DEFAULT_UNREACHABLE:%.*]] [315; CHECK-NEXT:      i8 1, label [[BB_1:%.*]]316; CHECK-NEXT:      i8 -1, label [[BB_NEG1:%.*]]317; CHECK-NEXT:      i8 0, label [[BB_0:%.*]]318; CHECK-NEXT:    ]319; CHECK:       bb.neg2:320; CHECK-NEXT:    ret i8 -2321; CHECK:       bb.neg1:322; CHECK-NEXT:    ret i8 -1323; CHECK:       bb.0:324; CHECK-NEXT:    ret i8 0325; CHECK:       bb.1:326; CHECK-NEXT:    ret i8 1327; CHECK:       bb.2:328; CHECK-NEXT:    ret i8 2329; CHECK:       default.unreachable:330; CHECK-NEXT:    unreachable331; CHECK:       default:332; CHECK-NEXT:    ret i8 123333;334  %cmp = call range(i8 -2, 3) i8 @llvm.ucmp(i32 %x, i32 %y)335  switch i8 %cmp, label %default [336  i8 -2, label %bb.neg2337  i8 -1, label %bb.neg1338  i8 0, label %bb.0339  i8 1, label %bb.1340  i8 2, label %bb.2341  ]342 343bb.neg2:344  ret i8 -2345 346bb.neg1:347  ret i8 -1348 349bb.0:350  ret i8 0351 352bb.1:353  ret i8 1354 355bb.2:356  ret i8 2357 358default:359  ret i8 123360}361 362define i8 @scmp_switch(i32 %x, i32 %y) {363; CHECK-LABEL: @scmp_switch(364; CHECK-NEXT:    [[CMP:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X:%.*]], i32 [[Y:%.*]])365; CHECK-NEXT:    switch i8 [[CMP]], label [[DEFAULT_UNREACHABLE:%.*]] [366; CHECK-NEXT:      i8 1, label [[BB_1:%.*]]367; CHECK-NEXT:      i8 -1, label [[BB_NEG1:%.*]]368; CHECK-NEXT:      i8 0, label [[BB_0:%.*]]369; CHECK-NEXT:    ]370; CHECK:       bb.neg2:371; CHECK-NEXT:    ret i8 -2372; CHECK:       bb.neg1:373; CHECK-NEXT:    ret i8 -1374; CHECK:       bb.0:375; CHECK-NEXT:    ret i8 0376; CHECK:       bb.1:377; CHECK-NEXT:    ret i8 1378; CHECK:       bb.2:379; CHECK-NEXT:    ret i8 2380; CHECK:       default.unreachable:381; CHECK-NEXT:    unreachable382; CHECK:       default:383; CHECK-NEXT:    ret i8 123384;385  %cmp = call i8 @llvm.scmp(i32 %x, i32 %y)386  switch i8 %cmp, label %default [387  i8 -2, label %bb.neg2388  i8 -1, label %bb.neg1389  i8 0, label %bb.0390  i8 1, label %bb.1391  i8 2, label %bb.2392  ]393 394bb.neg2:395  ret i8 -2396 397bb.neg1:398  ret i8 -1399 400bb.0:401  ret i8 0402 403bb.1:404  ret i8 1405 406bb.2:407  ret i8 2408 409default:410  ret i8 123411}412