brintos

brintos / llvm-project-archived public Read only

0
0
Text · 23.6 KiB · e7339f4 Raw
687 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s3 4target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"5target triple = "thumbv7m-arm-none-eabi"6 7define void @h(ptr nocapture %p, i32 %x) local_unnamed_addr #0 {8; CHECK-LABEL: @h(9; CHECK-NEXT:  entry:10; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], 011; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]12; CHECK:       if.then:13; CHECK-NEXT:    [[REM21:%.*]] = urem i32 [[X]], 1014; CHECK-NEXT:    store i32 [[REM21]], ptr [[P:%.*]], align 415; CHECK-NEXT:    br label [[IF_END]]16; CHECK:       if.end:17; CHECK-NEXT:    ret void18;19entry:20 21  %cmp = icmp sgt i32 %x, 022  br i1 %cmp, label %if.then, label %if.end23 24if.then:25  %rem2 = srem i32 %x, 1026  store i32 %rem2, ptr %p, align 427  br label %if.end28 29if.end:30  ret void31}32 33; looping case where loop has exactly one block34; at the point of srem, we know that %a is always greater than 0,35; because of the assume before it, so we can transform it to urem.36declare void @llvm.assume(i1)37define void @test4(i32 %n) {38; CHECK-LABEL: @test4(39; CHECK-NEXT:  entry:40; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[N:%.*]], 041; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP:%.*]], label [[EXIT:%.*]]42; CHECK:       loop:43; CHECK-NEXT:    [[A:%.*]] = phi i32 [ [[N]], [[ENTRY:%.*]] ], [ [[REM1:%.*]], [[LOOP]] ]44; CHECK-NEXT:    [[COND:%.*]] = icmp samesign ugt i32 [[A]], 445; CHECK-NEXT:    call void @llvm.assume(i1 [[COND]])46; CHECK-NEXT:    [[REM1]] = urem i32 [[A]], 1747; CHECK-NEXT:    [[LOOPCOND:%.*]] = icmp samesign ugt i32 [[REM1]], 848; CHECK-NEXT:    br i1 [[LOOPCOND]], label [[LOOP]], label [[EXIT]]49; CHECK:       exit:50; CHECK-NEXT:    ret void51;52entry:53  %cmp = icmp sgt i32 %n, 054  br i1 %cmp, label %loop, label %exit55 56loop:57  %a = phi i32 [ %n, %entry ], [ %rem, %loop ]58  %cond = icmp sgt i32 %a, 459  call void @llvm.assume(i1 %cond)60  %rem = srem i32 %a, 1761  %loopcond = icmp sgt i32 %rem, 862  br i1 %loopcond, label %loop, label %exit63 64exit:65  ret void66}67 68; Now, let's try various domain combinations for operands.69 70define i8 @test5_pos_pos(i8 %x, i8 %y) {71; CHECK-LABEL: @test5_pos_pos(72; CHECK-NEXT:    [[C0:%.*]] = icmp sge i8 [[X:%.*]], 073; CHECK-NEXT:    call void @llvm.assume(i1 [[C0]])74; CHECK-NEXT:    [[C1:%.*]] = icmp sge i8 [[Y:%.*]], 075; CHECK-NEXT:    call void @llvm.assume(i1 [[C1]])76; CHECK-NEXT:    [[REM1:%.*]] = urem i8 [[X]], [[Y]]77; CHECK-NEXT:    ret i8 [[REM1]]78;79  %c0 = icmp sge i8 %x, 080  call void @llvm.assume(i1 %c0)81  %c1 = icmp sge i8 %y, 082  call void @llvm.assume(i1 %c1)83 84  %rem = srem i8 %x, %y85  ret i8 %rem86}87define i8 @test6_pos_neg(i8 %x, i8 %y) {88; CHECK-LABEL: @test6_pos_neg(89; CHECK-NEXT:    [[C0:%.*]] = icmp sge i8 [[X:%.*]], 090; CHECK-NEXT:    call void @llvm.assume(i1 [[C0]])91; CHECK-NEXT:    [[C1:%.*]] = icmp sle i8 [[Y:%.*]], 092; CHECK-NEXT:    call void @llvm.assume(i1 [[C1]])93; CHECK-NEXT:    [[Y_NONNEG:%.*]] = sub i8 0, [[Y]]94; CHECK-NEXT:    [[REM1:%.*]] = urem i8 [[X]], [[Y_NONNEG]]95; CHECK-NEXT:    ret i8 [[REM1]]96;97  %c0 = icmp sge i8 %x, 098  call void @llvm.assume(i1 %c0)99  %c1 = icmp sle i8 %y, 0100  call void @llvm.assume(i1 %c1)101 102  %rem = srem i8 %x, %y103  ret i8 %rem104}105define i8 @test7_neg_pos(i8 %x, i8 %y) {106; CHECK-LABEL: @test7_neg_pos(107; CHECK-NEXT:    [[C0:%.*]] = icmp sle i8 [[X:%.*]], 0108; CHECK-NEXT:    call void @llvm.assume(i1 [[C0]])109; CHECK-NEXT:    [[C1:%.*]] = icmp sge i8 [[Y:%.*]], 0110; CHECK-NEXT:    call void @llvm.assume(i1 [[C1]])111; CHECK-NEXT:    [[X_NONNEG:%.*]] = sub i8 0, [[X]]112; CHECK-NEXT:    [[REM1:%.*]] = urem i8 [[X_NONNEG]], [[Y]]113; CHECK-NEXT:    [[REM1_NEG:%.*]] = sub i8 0, [[REM1]]114; CHECK-NEXT:    ret i8 [[REM1_NEG]]115;116  %c0 = icmp sle i8 %x, 0117  call void @llvm.assume(i1 %c0)118  %c1 = icmp sge i8 %y, 0119  call void @llvm.assume(i1 %c1)120 121  %rem = srem i8 %x, %y122  ret i8 %rem123}124define i8 @test8_neg_neg(i8 %x, i8 %y) {125; CHECK-LABEL: @test8_neg_neg(126; CHECK-NEXT:    [[C0:%.*]] = icmp sle i8 [[X:%.*]], 0127; CHECK-NEXT:    call void @llvm.assume(i1 [[C0]])128; CHECK-NEXT:    [[C1:%.*]] = icmp sle i8 [[Y:%.*]], 0129; CHECK-NEXT:    call void @llvm.assume(i1 [[C1]])130; CHECK-NEXT:    [[X_NONNEG:%.*]] = sub i8 0, [[X]]131; CHECK-NEXT:    [[Y_NONNEG:%.*]] = sub i8 0, [[Y]]132; CHECK-NEXT:    [[REM1:%.*]] = urem i8 [[X_NONNEG]], [[Y_NONNEG]]133; CHECK-NEXT:    [[REM1_NEG:%.*]] = sub i8 0, [[REM1]]134; CHECK-NEXT:    ret i8 [[REM1_NEG]]135;136  %c0 = icmp sle i8 %x, 0137  call void @llvm.assume(i1 %c0)138  %c1 = icmp sle i8 %y, 0139  call void @llvm.assume(i1 %c1)140 141  %rem = srem i8 %x, %y142  ret i8 %rem143}144 145; After making remainder unsigned, can we narrow it?146define i16 @test9_narrow(i16 %x, i16 %y) {147; CHECK-LABEL: @test9_narrow(148; CHECK-NEXT:    [[C0:%.*]] = icmp ult i16 [[X:%.*]], 128149; CHECK-NEXT:    call void @llvm.assume(i1 [[C0]])150; CHECK-NEXT:    [[C1:%.*]] = icmp ult i16 [[Y:%.*]], 128151; CHECK-NEXT:    call void @llvm.assume(i1 [[C1]])152; CHECK-NEXT:    [[REM1_LHS_TRUNC:%.*]] = trunc i16 [[X]] to i8153; CHECK-NEXT:    [[REM1_RHS_TRUNC:%.*]] = trunc i16 [[Y]] to i8154; CHECK-NEXT:    [[REM12:%.*]] = urem i8 [[REM1_LHS_TRUNC]], [[REM1_RHS_TRUNC]]155; CHECK-NEXT:    [[REM1_ZEXT:%.*]] = zext i8 [[REM12]] to i16156; CHECK-NEXT:    ret i16 [[REM1_ZEXT]]157;158  %c0 = icmp ult i16 %x, 128159  call void @llvm.assume(i1 %c0)160  %c1 = icmp ult i16 %y, 128161  call void @llvm.assume(i1 %c1)162 163  %rem = srem i16 %x, %y164  ret i16 %rem165}166 167; Ok, but what about narrowing srem in general?168 169; If both operands are i15, it's uncontroversial - we can truncate to i16170define i64 @test11_i15_i15(i64 %x, i64 %y) {171; CHECK-LABEL: @test11_i15_i15(172; CHECK-NEXT:  entry:173; CHECK-NEXT:    [[C0:%.*]] = icmp sle i64 [[X:%.*]], 16383174; CHECK-NEXT:    call void @llvm.assume(i1 [[C0]])175; CHECK-NEXT:    [[C1:%.*]] = icmp sge i64 [[X]], -16384176; CHECK-NEXT:    call void @llvm.assume(i1 [[C1]])177; CHECK-NEXT:    [[C2:%.*]] = icmp sle i64 [[Y:%.*]], 16383178; CHECK-NEXT:    call void @llvm.assume(i1 [[C2]])179; CHECK-NEXT:    [[C3:%.*]] = icmp sge i64 [[Y]], -16384180; CHECK-NEXT:    call void @llvm.assume(i1 [[C3]])181; CHECK-NEXT:    [[DIV_LHS_TRUNC:%.*]] = trunc i64 [[X]] to i16182; CHECK-NEXT:    [[DIV_RHS_TRUNC:%.*]] = trunc i64 [[Y]] to i16183; CHECK-NEXT:    [[DIV1:%.*]] = srem i16 [[DIV_LHS_TRUNC]], [[DIV_RHS_TRUNC]]184; CHECK-NEXT:    [[DIV_SEXT:%.*]] = sext i16 [[DIV1]] to i64185; CHECK-NEXT:    ret i64 [[DIV_SEXT]]186;187entry:188  %c0 = icmp sle i64 %x, 16383189  call void @llvm.assume(i1 %c0)190  %c1 = icmp sge i64 %x, -16384191  call void @llvm.assume(i1 %c1)192 193  %c2 = icmp sle i64 %y, 16383194  call void @llvm.assume(i1 %c2)195  %c3 = icmp sge i64 %y, -16384196  call void @llvm.assume(i1 %c3)197 198  %div = srem i64 %x, %y199  ret i64 %div200}201 202; But if operands are i16, we can only truncate to i32, because we can't203; rule out UB of  i16 INT_MIN s/ i16 -1204define i64 @test12_i16_i16(i64 %x, i64 %y) {205; CHECK-LABEL: @test12_i16_i16(206; CHECK-NEXT:  entry:207; CHECK-NEXT:    [[C0:%.*]] = icmp sle i64 [[X:%.*]], 32767208; CHECK-NEXT:    call void @llvm.assume(i1 [[C0]])209; CHECK-NEXT:    [[C1:%.*]] = icmp sge i64 [[X]], -32768210; CHECK-NEXT:    call void @llvm.assume(i1 [[C1]])211; CHECK-NEXT:    [[C2:%.*]] = icmp sle i64 [[Y:%.*]], 32767212; CHECK-NEXT:    call void @llvm.assume(i1 [[C2]])213; CHECK-NEXT:    [[C3:%.*]] = icmp sge i64 [[Y]], -32768214; CHECK-NEXT:    call void @llvm.assume(i1 [[C3]])215; CHECK-NEXT:    [[DIV_LHS_TRUNC:%.*]] = trunc i64 [[X]] to i32216; CHECK-NEXT:    [[DIV_RHS_TRUNC:%.*]] = trunc i64 [[Y]] to i32217; CHECK-NEXT:    [[DIV1:%.*]] = srem i32 [[DIV_LHS_TRUNC]], [[DIV_RHS_TRUNC]]218; CHECK-NEXT:    [[DIV_SEXT:%.*]] = sext i32 [[DIV1]] to i64219; CHECK-NEXT:    ret i64 [[DIV_SEXT]]220;221entry:222  %c0 = icmp sle i64 %x, 32767223  call void @llvm.assume(i1 %c0)224  %c1 = icmp sge i64 %x, -32768225  call void @llvm.assume(i1 %c1)226 227  %c2 = icmp sle i64 %y, 32767228  call void @llvm.assume(i1 %c2)229  %c3 = icmp sge i64 %y, -32768230  call void @llvm.assume(i1 %c3)231 232  %div = srem i64 %x, %y233  ret i64 %div234}235 236; But if divident is i16, and divisor is u15, then we know that i16 is UB-safe.237define i64 @test13_i16_u15(i64 %x, i64 %y) {238; CHECK-LABEL: @test13_i16_u15(239; CHECK-NEXT:  entry:240; CHECK-NEXT:    [[C0:%.*]] = icmp sle i64 [[X:%.*]], 32767241; CHECK-NEXT:    call void @llvm.assume(i1 [[C0]])242; CHECK-NEXT:    [[C1:%.*]] = icmp sge i64 [[X]], -32768243; CHECK-NEXT:    call void @llvm.assume(i1 [[C1]])244; CHECK-NEXT:    [[C2:%.*]] = icmp ule i64 [[Y:%.*]], 32767245; CHECK-NEXT:    call void @llvm.assume(i1 [[C2]])246; CHECK-NEXT:    [[DIV_LHS_TRUNC:%.*]] = trunc i64 [[X]] to i16247; CHECK-NEXT:    [[DIV_RHS_TRUNC:%.*]] = trunc i64 [[Y]] to i16248; CHECK-NEXT:    [[DIV1:%.*]] = srem i16 [[DIV_LHS_TRUNC]], [[DIV_RHS_TRUNC]]249; CHECK-NEXT:    [[DIV_SEXT:%.*]] = sext i16 [[DIV1]] to i64250; CHECK-NEXT:    ret i64 [[DIV_SEXT]]251;252entry:253  %c0 = icmp sle i64 %x, 32767254  call void @llvm.assume(i1 %c0)255  %c1 = icmp sge i64 %x, -32768256  call void @llvm.assume(i1 %c1)257 258  %c2 = icmp ule i64 %y, 32767259  call void @llvm.assume(i1 %c2)260 261  %div = srem i64 %x, %y262  ret i64 %div263}264 265; And likewise, if we know that if the divident is never i16 INT_MIN,266; we can truncate to i16.267define i64 @test14_i16safe_i16(i64 %x, i64 %y) {268; CHECK-LABEL: @test14_i16safe_i16(269; CHECK-NEXT:  entry:270; CHECK-NEXT:    [[C0:%.*]] = icmp sle i64 [[X:%.*]], 32767271; CHECK-NEXT:    call void @llvm.assume(i1 [[C0]])272; CHECK-NEXT:    [[C1:%.*]] = icmp sgt i64 [[X]], -32768273; CHECK-NEXT:    call void @llvm.assume(i1 [[C1]])274; CHECK-NEXT:    [[C2:%.*]] = icmp sle i64 [[Y:%.*]], 32767275; CHECK-NEXT:    call void @llvm.assume(i1 [[C2]])276; CHECK-NEXT:    [[C3:%.*]] = icmp sge i64 [[Y]], -32768277; CHECK-NEXT:    call void @llvm.assume(i1 [[C3]])278; CHECK-NEXT:    [[DIV_LHS_TRUNC:%.*]] = trunc i64 [[X]] to i16279; CHECK-NEXT:    [[DIV_RHS_TRUNC:%.*]] = trunc i64 [[Y]] to i16280; CHECK-NEXT:    [[DIV1:%.*]] = srem i16 [[DIV_LHS_TRUNC]], [[DIV_RHS_TRUNC]]281; CHECK-NEXT:    [[DIV_SEXT:%.*]] = sext i16 [[DIV1]] to i64282; CHECK-NEXT:    ret i64 [[DIV_SEXT]]283;284entry:285  %c0 = icmp sle i64 %x, 32767286  call void @llvm.assume(i1 %c0)287  %c1 = icmp sgt i64 %x, -32768288  call void @llvm.assume(i1 %c1)289 290  %c2 = icmp sle i64 %y, 32767291  call void @llvm.assume(i1 %c2)292  %c3 = icmp sge i64 %y, -32768293  call void @llvm.assume(i1 %c3)294 295  %div = srem i64 %x, %y296  ret i64 %div297}298 299; Of course, both of the conditions can happen at once.300define i64 @test15_i16safe_u15(i64 %x, i64 %y) {301; CHECK-LABEL: @test15_i16safe_u15(302; CHECK-NEXT:  entry:303; CHECK-NEXT:    [[C0:%.*]] = icmp sle i64 [[X:%.*]], 32767304; CHECK-NEXT:    call void @llvm.assume(i1 [[C0]])305; CHECK-NEXT:    [[C1:%.*]] = icmp sgt i64 [[X]], -32768306; CHECK-NEXT:    call void @llvm.assume(i1 [[C1]])307; CHECK-NEXT:    [[C2:%.*]] = icmp ule i64 [[Y:%.*]], 32767308; CHECK-NEXT:    call void @llvm.assume(i1 [[C2]])309; CHECK-NEXT:    [[DIV_LHS_TRUNC:%.*]] = trunc i64 [[X]] to i16310; CHECK-NEXT:    [[DIV_RHS_TRUNC:%.*]] = trunc i64 [[Y]] to i16311; CHECK-NEXT:    [[DIV1:%.*]] = srem i16 [[DIV_LHS_TRUNC]], [[DIV_RHS_TRUNC]]312; CHECK-NEXT:    [[DIV_SEXT:%.*]] = sext i16 [[DIV1]] to i64313; CHECK-NEXT:    ret i64 [[DIV_SEXT]]314;315entry:316  %c0 = icmp sle i64 %x, 32767317  call void @llvm.assume(i1 %c0)318  %c1 = icmp sgt i64 %x, -32768319  call void @llvm.assume(i1 %c1)320 321  %c2 = icmp ule i64 %y, 32767322  call void @llvm.assume(i1 %c2)323 324  %div = srem i64 %x, %y325  ret i64 %div326}327 328; We at most truncate to i8329define i64 @test16_i4_i4(i64 %x, i64 %y) {330; CHECK-LABEL: @test16_i4_i4(331; CHECK-NEXT:  entry:332; CHECK-NEXT:    [[C0:%.*]] = icmp sle i64 [[X:%.*]], 3333; CHECK-NEXT:    call void @llvm.assume(i1 [[C0]])334; CHECK-NEXT:    [[C1:%.*]] = icmp sge i64 [[X]], -4335; CHECK-NEXT:    call void @llvm.assume(i1 [[C1]])336; CHECK-NEXT:    [[C2:%.*]] = icmp sle i64 [[Y:%.*]], 3337; CHECK-NEXT:    call void @llvm.assume(i1 [[C2]])338; CHECK-NEXT:    [[C3:%.*]] = icmp sge i64 [[Y]], -4339; CHECK-NEXT:    call void @llvm.assume(i1 [[C3]])340; CHECK-NEXT:    [[DIV_LHS_TRUNC:%.*]] = trunc i64 [[X]] to i8341; CHECK-NEXT:    [[DIV_RHS_TRUNC:%.*]] = trunc i64 [[Y]] to i8342; CHECK-NEXT:    [[DIV1:%.*]] = srem i8 [[DIV_LHS_TRUNC]], [[DIV_RHS_TRUNC]]343; CHECK-NEXT:    [[DIV_SEXT:%.*]] = sext i8 [[DIV1]] to i64344; CHECK-NEXT:    ret i64 [[DIV_SEXT]]345;346entry:347  %c0 = icmp sle i64 %x, 3348  call void @llvm.assume(i1 %c0)349  %c1 = icmp sge i64 %x, -4350  call void @llvm.assume(i1 %c1)351 352  %c2 = icmp sle i64 %y, 3353  call void @llvm.assume(i1 %c2)354  %c3 = icmp sge i64 %y, -4355  call void @llvm.assume(i1 %c3)356 357  %div = srem i64 %x, %y358  ret i64 %div359}360 361; And we round up to the powers of two362define i64 @test17_i9_i9(i64 %x, i64 %y) {363; CHECK-LABEL: @test17_i9_i9(364; CHECK-NEXT:  entry:365; CHECK-NEXT:    [[C0:%.*]] = icmp sle i64 [[X:%.*]], 255366; CHECK-NEXT:    call void @llvm.assume(i1 [[C0]])367; CHECK-NEXT:    [[C1:%.*]] = icmp sge i64 [[X]], -256368; CHECK-NEXT:    call void @llvm.assume(i1 [[C1]])369; CHECK-NEXT:    [[C2:%.*]] = icmp sle i64 [[Y:%.*]], 255370; CHECK-NEXT:    call void @llvm.assume(i1 [[C2]])371; CHECK-NEXT:    [[C3:%.*]] = icmp sge i64 [[Y]], -256372; CHECK-NEXT:    call void @llvm.assume(i1 [[C3]])373; CHECK-NEXT:    [[DIV_LHS_TRUNC:%.*]] = trunc i64 [[X]] to i16374; CHECK-NEXT:    [[DIV_RHS_TRUNC:%.*]] = trunc i64 [[Y]] to i16375; CHECK-NEXT:    [[DIV1:%.*]] = srem i16 [[DIV_LHS_TRUNC]], [[DIV_RHS_TRUNC]]376; CHECK-NEXT:    [[DIV_SEXT:%.*]] = sext i16 [[DIV1]] to i64377; CHECK-NEXT:    ret i64 [[DIV_SEXT]]378;379entry:380  %c0 = icmp sle i64 %x, 255381  call void @llvm.assume(i1 %c0)382  %c1 = icmp sge i64 %x, -256383  call void @llvm.assume(i1 %c1)384 385  %c2 = icmp sle i64 %y, 255386  call void @llvm.assume(i1 %c2)387  %c3 = icmp sge i64 %y, -256388  call void @llvm.assume(i1 %c3)389 390  %div = srem i64 %x, %y391  ret i64 %div392}393 394; Don't widen the operation to the next power of two if it wasn't a power of two.395define i9 @test18_i9_i9(i9 %x, i9 %y) {396; CHECK-LABEL: @test18_i9_i9(397; CHECK-NEXT:  entry:398; CHECK-NEXT:    [[C0:%.*]] = icmp sle i9 [[X:%.*]], 255399; CHECK-NEXT:    call void @llvm.assume(i1 [[C0]])400; CHECK-NEXT:    [[C1:%.*]] = icmp sge i9 [[X]], -256401; CHECK-NEXT:    call void @llvm.assume(i1 [[C1]])402; CHECK-NEXT:    [[C2:%.*]] = icmp sle i9 [[Y:%.*]], 255403; CHECK-NEXT:    call void @llvm.assume(i1 [[C2]])404; CHECK-NEXT:    [[C3:%.*]] = icmp sge i9 [[Y]], -256405; CHECK-NEXT:    call void @llvm.assume(i1 [[C3]])406; CHECK-NEXT:    [[DIV:%.*]] = srem i9 [[X]], [[Y]]407; CHECK-NEXT:    ret i9 [[DIV]]408;409entry:410  %c0 = icmp sle i9 %x, 255411  call void @llvm.assume(i1 %c0)412  %c1 = icmp sge i9 %x, -256413  call void @llvm.assume(i1 %c1)414 415  %c2 = icmp sle i9 %y, 255416  call void @llvm.assume(i1 %c2)417  %c3 = icmp sge i9 %y, -256418  call void @llvm.assume(i1 %c3)419 420  %div = srem i9 %x, %y421  ret i9 %div422}423define i10 @test19_i10_i10(i10 %x, i10 %y) {424; CHECK-LABEL: @test19_i10_i10(425; CHECK-NEXT:  entry:426; CHECK-NEXT:    [[C0:%.*]] = icmp sle i10 [[X:%.*]], 255427; CHECK-NEXT:    call void @llvm.assume(i1 [[C0]])428; CHECK-NEXT:    [[C1:%.*]] = icmp sge i10 [[X]], -256429; CHECK-NEXT:    call void @llvm.assume(i1 [[C1]])430; CHECK-NEXT:    [[C2:%.*]] = icmp sle i10 [[Y:%.*]], 255431; CHECK-NEXT:    call void @llvm.assume(i1 [[C2]])432; CHECK-NEXT:    [[C3:%.*]] = icmp sge i10 [[Y]], -256433; CHECK-NEXT:    call void @llvm.assume(i1 [[C3]])434; CHECK-NEXT:    [[DIV:%.*]] = srem i10 [[X]], [[Y]]435; CHECK-NEXT:    ret i10 [[DIV]]436;437entry:438  %c0 = icmp sle i10 %x, 255439  call void @llvm.assume(i1 %c0)440  %c1 = icmp sge i10 %x, -256441  call void @llvm.assume(i1 %c1)442 443  %c2 = icmp sle i10 %y, 255444  call void @llvm.assume(i1 %c2)445  %c3 = icmp sge i10 %y, -256446  call void @llvm.assume(i1 %c3)447 448  %div = srem i10 %x, %y449  ret i10 %div450}451 452; Note that we need to take the maximal bitwidth, in which both of the operands are representable!453define i64 @test20_i16_i18(i64 %x, i64 %y) {454; CHECK-LABEL: @test20_i16_i18(455; CHECK-NEXT:  entry:456; CHECK-NEXT:    [[C0:%.*]] = icmp sle i64 [[X:%.*]], 16383457; CHECK-NEXT:    call void @llvm.assume(i1 [[C0]])458; CHECK-NEXT:    [[C1:%.*]] = icmp sge i64 [[X]], -16384459; CHECK-NEXT:    call void @llvm.assume(i1 [[C1]])460; CHECK-NEXT:    [[C2:%.*]] = icmp sle i64 [[Y:%.*]], 65535461; CHECK-NEXT:    call void @llvm.assume(i1 [[C2]])462; CHECK-NEXT:    [[C3:%.*]] = icmp sge i64 [[Y]], -65536463; CHECK-NEXT:    call void @llvm.assume(i1 [[C3]])464; CHECK-NEXT:    [[DIV_LHS_TRUNC:%.*]] = trunc i64 [[X]] to i32465; CHECK-NEXT:    [[DIV_RHS_TRUNC:%.*]] = trunc i64 [[Y]] to i32466; CHECK-NEXT:    [[DIV1:%.*]] = srem i32 [[DIV_LHS_TRUNC]], [[DIV_RHS_TRUNC]]467; CHECK-NEXT:    [[DIV_SEXT:%.*]] = sext i32 [[DIV1]] to i64468; CHECK-NEXT:    ret i64 [[DIV_SEXT]]469;470entry:471  %c0 = icmp sle i64 %x, 16383472  call void @llvm.assume(i1 %c0)473  %c1 = icmp sge i64 %x, -16384474  call void @llvm.assume(i1 %c1)475 476  %c2 = icmp sle i64 %y, 65535477  call void @llvm.assume(i1 %c2)478  %c3 = icmp sge i64 %y, -65536479  call void @llvm.assume(i1 %c3)480 481  %div = srem i64 %x, %y482  ret i64 %div483}484define i64 @test21_i18_i16(i64 %x, i64 %y) {485; CHECK-LABEL: @test21_i18_i16(486; CHECK-NEXT:  entry:487; CHECK-NEXT:    [[C0:%.*]] = icmp sle i64 [[X:%.*]], 65535488; CHECK-NEXT:    call void @llvm.assume(i1 [[C0]])489; CHECK-NEXT:    [[C1:%.*]] = icmp sge i64 [[X]], -65536490; CHECK-NEXT:    call void @llvm.assume(i1 [[C1]])491; CHECK-NEXT:    [[C2:%.*]] = icmp sle i64 [[Y:%.*]], 16383492; CHECK-NEXT:    call void @llvm.assume(i1 [[C2]])493; CHECK-NEXT:    [[C3:%.*]] = icmp sge i64 [[Y]], -16384494; CHECK-NEXT:    call void @llvm.assume(i1 [[C3]])495; CHECK-NEXT:    [[DIV_LHS_TRUNC:%.*]] = trunc i64 [[X]] to i32496; CHECK-NEXT:    [[DIV_RHS_TRUNC:%.*]] = trunc i64 [[Y]] to i32497; CHECK-NEXT:    [[DIV1:%.*]] = srem i32 [[DIV_LHS_TRUNC]], [[DIV_RHS_TRUNC]]498; CHECK-NEXT:    [[DIV_SEXT:%.*]] = sext i32 [[DIV1]] to i64499; CHECK-NEXT:    ret i64 [[DIV_SEXT]]500;501entry:502  %c0 = icmp sle i64 %x, 65535503  call void @llvm.assume(i1 %c0)504  %c1 = icmp sge i64 %x, -65536505  call void @llvm.assume(i1 %c1)506 507  %c2 = icmp sle i64 %y, 16383508  call void @llvm.assume(i1 %c2)509  %c3 = icmp sge i64 %y, -16384510  call void @llvm.assume(i1 %c3)511 512  %div = srem i64 %x, %y513  ret i64 %div514}515 516define dso_local i8 @abs_x_lt_abs_y_positive(i8 %x, i8 %y) {517; CHECK-LABEL: @abs_x_lt_abs_y_positive(518; CHECK-NEXT:  entry:519; CHECK-NEXT:    [[X_CMP:%.*]] = icmp slt i8 [[X:%.*]], 10520; CHECK-NEXT:    [[X_CMP2:%.*]] = icmp sgt i8 [[X]], -10521; CHECK-NEXT:    [[AND_X:%.*]] = and i1 [[X_CMP]], [[X_CMP2]]522; CHECK-NEXT:    [[Y_CMP:%.*]] = icmp sge i8 [[Y:%.*]], 10523; CHECK-NEXT:    [[AND_COND:%.*]] = and i1 [[AND_X]], [[Y_CMP]]524; CHECK-NEXT:    br i1 [[AND_COND]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]525; CHECK:       if.else:526; CHECK-NEXT:    ret i8 [[X]]527; CHECK:       if.then:528; CHECK-NEXT:    ret i8 0529;530entry:531  %x.cmp = icmp slt i8 %x, 10532  %x.cmp2 = icmp sgt i8 %x, -10533  %and.x = and i1 %x.cmp, %x.cmp2534  %y.cmp = icmp sge i8 %y, 10535  %and.cond = and i1 %and.x, %y.cmp536  br i1 %and.cond, label %if.else, label %if.then537 538if.else:                                          ; preds = %entry539  %rem = srem i8 %x, %y540  ret i8 %rem541 542if.then:                                          ; preds = %entry, %if.then6, %if.end4543  ret i8 0544}545 546define dso_local i8 @abs_x_lt_abs_y_positive_unsigned_cmp(i8 %x, i8 %y) {547; CHECK-LABEL: @abs_x_lt_abs_y_positive_unsigned_cmp(548; CHECK-NEXT:  entry:549; CHECK-NEXT:    [[X_CMP:%.*]] = icmp slt i8 [[X:%.*]], 10550; CHECK-NEXT:    [[X_CMP2:%.*]] = icmp sgt i8 [[X]], -10551; CHECK-NEXT:    [[AND_X:%.*]] = and i1 [[X_CMP]], [[X_CMP2]]552; CHECK-NEXT:    [[Y_CMP:%.*]] = icmp uge i8 [[Y:%.*]], 10553; CHECK-NEXT:    [[Y_CMP2:%.*]] = icmp ule i8 [[Y]], 20554; CHECK-NEXT:    [[AND_Y:%.*]] = and i1 [[Y_CMP]], [[Y_CMP2]]555; CHECK-NEXT:    [[AND_COND:%.*]] = and i1 [[AND_X]], [[AND_Y]]556; CHECK-NEXT:    br i1 [[AND_COND]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]557; CHECK:       if.else:558; CHECK-NEXT:    ret i8 [[X]]559; CHECK:       if.then:560; CHECK-NEXT:    ret i8 0561;562entry:563  %x.cmp = icmp slt i8 %x, 10564  %x.cmp2 = icmp sgt i8 %x, -10565  %and.x = and i1 %x.cmp, %x.cmp2566  %y.cmp = icmp uge i8 %y, 10567  %y.cmp2 = icmp ule i8 %y, 20568  %and.y = and i1 %y.cmp, %y.cmp2569  %and.cond = and i1 %and.x, %and.y570  br i1 %and.cond, label %if.else, label %if.then571 572if.else:                                          ; preds = %entry573  %rem = srem i8 %x, %y574  ret i8 %rem575 576if.then:                                          ; preds = %entry, %if.then6, %if.end4577  ret i8 0578}579 580define dso_local i8 @abs_x_lt_abs_y_negative(i8 %x, i8 %y) {581; CHECK-LABEL: @abs_x_lt_abs_y_negative(582; CHECK-NEXT:  entry:583; CHECK-NEXT:    [[X_CMP:%.*]] = icmp slt i8 [[X:%.*]], 10584; CHECK-NEXT:    [[X_CMP2:%.*]] = icmp sgt i8 [[X]], -10585; CHECK-NEXT:    [[AND_X:%.*]] = and i1 [[X_CMP]], [[X_CMP2]]586; CHECK-NEXT:    [[Y_CMP:%.*]] = icmp sge i8 [[Y:%.*]], -20587; CHECK-NEXT:    [[Y_CMP2:%.*]] = icmp sle i8 [[Y]], -11588; CHECK-NEXT:    [[AND_Y:%.*]] = and i1 [[Y_CMP]], [[Y_CMP2]]589; CHECK-NEXT:    [[AND_COND:%.*]] = and i1 [[AND_X]], [[AND_Y]]590; CHECK-NEXT:    br i1 [[AND_COND]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]591; CHECK:       if.else:592; CHECK-NEXT:    ret i8 [[X]]593; CHECK:       if.then:594; CHECK-NEXT:    ret i8 0595;596entry:597  %x.cmp = icmp slt i8 %x, 10598  %x.cmp2 = icmp sgt i8 %x, -10599  %and.x = and i1 %x.cmp, %x.cmp2600  %y.cmp = icmp sge i8 %y, -20601  %y.cmp2 = icmp sle i8 %y, -11602  %and.y = and i1 %y.cmp, %y.cmp2603  %and.cond = and i1 %and.x, %and.y604  br i1 %and.cond, label %if.else, label %if.then605 606if.else:                                          ; preds = %entry607  %rem = srem i8 %x, %y608  ret i8 %rem609 610if.then:                                          ; preds = %entry, %if.then6, %if.end4611  ret i8 0612}613 614; Negative test: abs(x) less than or equal abs(y)615 616define dso_local i8 @abs_x_lte_abs_y(i8 %x, i8 %y) {617; CHECK-LABEL: @abs_x_lte_abs_y(618; CHECK-NEXT:  entry:619; CHECK-NEXT:    [[X_CMP:%.*]] = icmp slt i8 [[X:%.*]], 10620; CHECK-NEXT:    [[X_CMP2:%.*]] = icmp sgt i8 [[X]], -10621; CHECK-NEXT:    [[AND_X:%.*]] = and i1 [[X_CMP]], [[X_CMP2]]622; CHECK-NEXT:    [[Y_CMP:%.*]] = icmp sge i8 [[Y:%.*]], -20623; CHECK-NEXT:    [[Y_CMP2:%.*]] = icmp sle i8 [[Y]], -9624; CHECK-NEXT:    [[AND_Y:%.*]] = and i1 [[Y_CMP]], [[Y_CMP2]]625; CHECK-NEXT:    [[AND_COND:%.*]] = and i1 [[AND_X]], [[AND_Y]]626; CHECK-NEXT:    br i1 [[AND_COND]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]627; CHECK:       if.else:628; CHECK-NEXT:    [[REM:%.*]] = srem i8 [[X]], [[Y]]629; CHECK-NEXT:    ret i8 [[REM]]630; CHECK:       if.then:631; CHECK-NEXT:    ret i8 0632;633entry:634  %x.cmp = icmp slt i8 %x, 10635  %x.cmp2 = icmp sgt i8 %x, -10636  %and.x = and i1 %x.cmp, %x.cmp2637  %y.cmp = icmp sge i8 %y, -20638  %y.cmp2 = icmp sle i8 %y, -9639  %and.y = and i1 %y.cmp, %y.cmp2640  %and.cond = and i1 %and.x, %and.y641  br i1 %and.cond, label %if.else, label %if.then642 643if.else:                                          ; preds = %entry644  %rem = srem i8 %x, %y645  ret i8 %rem646 647if.then:                                          ; preds = %entry, %if.then6, %if.end4648  ret i8 0649}650 651; Negative test: abs(x) has unknown predication with abs(y)652 653define dso_local i8 @abs_x_unknown_abs_y(i8 %x, i8 %y) {654; CHECK-LABEL: @abs_x_unknown_abs_y(655; CHECK-NEXT:  entry:656; CHECK-NEXT:    [[X_CMP:%.*]] = icmp slt i8 [[X:%.*]], 10657; CHECK-NEXT:    [[X_CMP2:%.*]] = icmp sgt i8 [[X]], -10658; CHECK-NEXT:    [[AND_X:%.*]] = and i1 [[X_CMP]], [[X_CMP2]]659; CHECK-NEXT:    [[Y_CMP:%.*]] = icmp sge i8 [[Y:%.*]], -20660; CHECK-NEXT:    [[Y_CMP2:%.*]] = icmp sle i8 [[Y]], -9661; CHECK-NEXT:    [[AND_Y:%.*]] = and i1 [[Y_CMP]], [[Y_CMP2]]662; CHECK-NEXT:    [[AND_COND:%.*]] = and i1 [[AND_X]], [[AND_Y]]663; CHECK-NEXT:    br i1 [[AND_COND]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]664; CHECK:       if.else:665; CHECK-NEXT:    [[REM:%.*]] = srem i8 [[X]], [[Y]]666; CHECK-NEXT:    ret i8 [[REM]]667; CHECK:       if.then:668; CHECK-NEXT:    ret i8 0669;670entry:671  %x.cmp = icmp slt i8 %x, 10672  %x.cmp2 = icmp sgt i8 %x, -10673  %and.x = and i1 %x.cmp, %x.cmp2674  %y.cmp = icmp sge i8 %y, -20675  %y.cmp2 = icmp sle i8 %y, -9676  %and.y = and i1 %y.cmp, %y.cmp2677  %and.cond = and i1 %and.x, %and.y678  br i1 %and.cond, label %if.else, label %if.then679 680if.else:                                          ; preds = %entry681  %rem = srem i8 %x, %y682  ret i8 %rem683 684if.then:                                          ; preds = %entry, %if.then6, %if.end4685  ret i8 0686}687