brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.5 KiB · 08095c8 Raw
367 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=div-rem-pairs -S -mtriple=powerpc64-unknown-unknown | FileCheck %s3 4declare void @foo(i32, i32)5 6define void @decompose_illegal_srem_same_block(i32 %a, i32 %b) {7; CHECK-LABEL: @decompose_illegal_srem_same_block(8; CHECK-NEXT:    [[A_FROZEN:%.*]] = freeze i32 [[A:%.*]]9; CHECK-NEXT:    [[B_FROZEN:%.*]] = freeze i32 [[B:%.*]]10; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[A_FROZEN]], [[B_FROZEN]]11; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[DIV]], [[B_FROZEN]]12; CHECK-NEXT:    [[REM_DECOMPOSED:%.*]] = sub i32 [[A_FROZEN]], [[TMP1]]13; CHECK-NEXT:    call void @foo(i32 [[REM_DECOMPOSED]], i32 [[DIV]])14; CHECK-NEXT:    ret void15;16  %rem = srem i32 %a, %b17  %div = sdiv i32 %a, %b18  call void @foo(i32 %rem, i32 %div)19  ret void20}21 22define void @decompose_illegal_urem_same_block(i32 %a, i32 %b) {23; CHECK-LABEL: @decompose_illegal_urem_same_block(24; CHECK-NEXT:    [[A_FROZEN:%.*]] = freeze i32 [[A:%.*]]25; CHECK-NEXT:    [[B_FROZEN:%.*]] = freeze i32 [[B:%.*]]26; CHECK-NEXT:    [[DIV:%.*]] = udiv i32 [[A_FROZEN]], [[B_FROZEN]]27; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[DIV]], [[B_FROZEN]]28; CHECK-NEXT:    [[REM_DECOMPOSED:%.*]] = sub i32 [[A_FROZEN]], [[TMP1]]29; CHECK-NEXT:    call void @foo(i32 [[REM_DECOMPOSED]], i32 [[DIV]])30; CHECK-NEXT:    ret void31;32  %div = udiv i32 %a, %b33  %rem = urem i32 %a, %b34  call void @foo(i32 %rem, i32 %div)35  ret void36}37 38; Hoist and optionally decompose the sdiv because it's safe and free.39; PR31028 - https://bugs.llvm.org/show_bug.cgi?id=3102840 41define i32 @hoist_sdiv(i32 %a, i32 %b) {42; CHECK-LABEL: @hoist_sdiv(43; CHECK-NEXT:  entry:44; CHECK-NEXT:    [[A_FROZEN:%.*]] = freeze i32 [[A:%.*]]45; CHECK-NEXT:    [[B_FROZEN:%.*]] = freeze i32 [[B:%.*]]46; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[A_FROZEN]], [[B_FROZEN]]47; CHECK-NEXT:    [[TMP0:%.*]] = mul i32 [[DIV]], [[B_FROZEN]]48; CHECK-NEXT:    [[REM_DECOMPOSED:%.*]] = sub i32 [[A_FROZEN]], [[TMP0]]49; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[REM_DECOMPOSED]], 4250; CHECK-NEXT:    br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]51; CHECK:       if:52; CHECK-NEXT:    br label [[END]]53; CHECK:       end:54; CHECK-NEXT:    [[RET:%.*]] = phi i32 [ [[DIV]], [[IF]] ], [ 3, [[ENTRY:%.*]] ]55; CHECK-NEXT:    ret i32 [[RET]]56;57entry:58  %rem = srem i32 %a, %b59  %cmp = icmp eq i32 %rem, 4260  br i1 %cmp, label %if, label %end61 62if:63  %div = sdiv i32 %a, %b64  br label %end65 66end:67  %ret = phi i32 [ %div, %if ], [ 3, %entry ]68  ret i32 %ret69}70 71; Hoist and optionally decompose the udiv because it's safe and free.72 73define i64 @hoist_udiv(i64 %a, i64 %b) {74; CHECK-LABEL: @hoist_udiv(75; CHECK-NEXT:  entry:76; CHECK-NEXT:    [[A_FROZEN:%.*]] = freeze i64 [[A:%.*]]77; CHECK-NEXT:    [[B_FROZEN:%.*]] = freeze i64 [[B:%.*]]78; CHECK-NEXT:    [[DIV:%.*]] = udiv i64 [[A_FROZEN]], [[B_FROZEN]]79; CHECK-NEXT:    [[TMP0:%.*]] = mul i64 [[DIV]], [[B_FROZEN]]80; CHECK-NEXT:    [[REM_DECOMPOSED:%.*]] = sub i64 [[A_FROZEN]], [[TMP0]]81; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[REM_DECOMPOSED]], 4282; CHECK-NEXT:    br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]83; CHECK:       if:84; CHECK-NEXT:    br label [[END]]85; CHECK:       end:86; CHECK-NEXT:    [[RET:%.*]] = phi i64 [ [[DIV]], [[IF]] ], [ 3, [[ENTRY:%.*]] ]87; CHECK-NEXT:    ret i64 [[RET]]88;89entry:90  %rem = urem i64 %a, %b91  %cmp = icmp eq i64 %rem, 4292  br i1 %cmp, label %if, label %end93 94if:95  %div = udiv i64 %a, %b96  br label %end97 98end:99  %ret = phi i64 [ %div, %if ], [ 3, %entry ]100  ret i64 %ret101}102 103; Hoist the srem if it's safe and free, otherwise decompose it.104 105define i16 @hoist_srem(i16 %a, i16 %b) {106; CHECK-LABEL: @hoist_srem(107; CHECK-NEXT:  entry:108; CHECK-NEXT:    [[A_FROZEN:%.*]] = freeze i16 [[A:%.*]]109; CHECK-NEXT:    [[B_FROZEN:%.*]] = freeze i16 [[B:%.*]]110; CHECK-NEXT:    [[DIV:%.*]] = sdiv i16 [[A_FROZEN]], [[B_FROZEN]]111; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i16 [[DIV]], 42112; CHECK-NEXT:    br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]113; CHECK:       if:114; CHECK-NEXT:    [[TMP0:%.*]] = mul i16 [[DIV]], [[B_FROZEN]]115; CHECK-NEXT:    [[REM_DECOMPOSED:%.*]] = sub i16 [[A_FROZEN]], [[TMP0]]116; CHECK-NEXT:    br label [[END]]117; CHECK:       end:118; CHECK-NEXT:    [[RET:%.*]] = phi i16 [ [[REM_DECOMPOSED]], [[IF]] ], [ 3, [[ENTRY:%.*]] ]119; CHECK-NEXT:    ret i16 [[RET]]120;121entry:122  %div = sdiv i16 %a, %b123  %cmp = icmp eq i16 %div, 42124  br i1 %cmp, label %if, label %end125 126if:127  %rem = srem i16 %a, %b128  br label %end129 130end:131  %ret = phi i16 [ %rem, %if ], [ 3, %entry ]132  ret i16 %ret133}134 135; Hoist the urem if it's safe and free, otherwise decompose it.136 137define i8 @hoist_urem(i8 %a, i8 %b) {138; CHECK-LABEL: @hoist_urem(139; CHECK-NEXT:  entry:140; CHECK-NEXT:    [[A_FROZEN:%.*]] = freeze i8 [[A:%.*]]141; CHECK-NEXT:    [[B_FROZEN:%.*]] = freeze i8 [[B:%.*]]142; CHECK-NEXT:    [[DIV:%.*]] = udiv i8 [[A_FROZEN]], [[B_FROZEN]]143; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[DIV]], 42144; CHECK-NEXT:    br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]145; CHECK:       if:146; CHECK-NEXT:    [[TMP0:%.*]] = mul i8 [[DIV]], [[B_FROZEN]]147; CHECK-NEXT:    [[REM_DECOMPOSED:%.*]] = sub i8 [[A_FROZEN]], [[TMP0]]148; CHECK-NEXT:    br label [[END]]149; CHECK:       end:150; CHECK-NEXT:    [[RET:%.*]] = phi i8 [ [[REM_DECOMPOSED]], [[IF]] ], [ 3, [[ENTRY:%.*]] ]151; CHECK-NEXT:    ret i8 [[RET]]152;153entry:154  %div = udiv i8 %a, %b155  %cmp = icmp eq i8 %div, 42156  br i1 %cmp, label %if, label %end157 158if:159  %rem = urem i8 %a, %b160  br label %end161 162end:163  %ret = phi i8 [ %rem, %if ], [ 3, %entry ]164  ret i8 %ret165}166 167; Be careful with RAUW/invalidation if this is a srem-of-srem.168 169define i32 @srem_of_srem_unexpanded(i32 %X, i32 %Y, i32 %Z) {170; CHECK-LABEL: @srem_of_srem_unexpanded(171; CHECK-NEXT:    [[T0:%.*]] = mul nsw i32 [[Z:%.*]], [[Y:%.*]]172; CHECK-NEXT:    [[X_FROZEN:%.*]] = freeze i32 [[X:%.*]]173; CHECK-NEXT:    [[T0_FROZEN:%.*]] = freeze i32 [[T0]]174; CHECK-NEXT:    [[T1:%.*]] = sdiv i32 [[X_FROZEN]], [[T0_FROZEN]]175; CHECK-NEXT:    [[T2:%.*]] = mul nsw i32 [[T0]], [[T1]]176; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[T1]], [[T0_FROZEN]]177; CHECK-NEXT:    [[T3_DECOMPOSED:%.*]] = sub i32 [[X_FROZEN]], [[TMP1]]178; CHECK-NEXT:    [[Y_FROZEN:%.*]] = freeze i32 [[Y]]179; CHECK-NEXT:    [[T4:%.*]] = sdiv i32 [[T3_DECOMPOSED]], [[Y_FROZEN]]180; CHECK-NEXT:    [[T5:%.*]] = mul nsw i32 [[T4]], [[Y]]181; CHECK-NEXT:    [[TMP2:%.*]] = mul i32 [[T4]], [[Y_FROZEN]]182; CHECK-NEXT:    [[T6_DECOMPOSED:%.*]] = sub i32 [[T3_DECOMPOSED]], [[TMP2]]183; CHECK-NEXT:    ret i32 [[T6_DECOMPOSED]]184;185  %t0 = mul nsw i32 %Z, %Y186  %t1 = sdiv i32 %X, %t0187  %t2 = mul nsw i32 %t0, %t1188  %t3 = srem i32 %X, %t0189  %t4 = sdiv i32 %t3, %Y190  %t5 = mul nsw i32 %t4, %Y191  %t6 = srem i32 %t3, %Y192  ret i32 %t6193}194define i32 @srem_of_srem_expanded(i32 %X, i32 %Y, i32 %Z) {195; CHECK-LABEL: @srem_of_srem_expanded(196; CHECK-NEXT:    [[T0:%.*]] = mul nsw i32 [[Z:%.*]], [[Y:%.*]]197; CHECK-NEXT:    [[T1:%.*]] = sdiv i32 [[X:%.*]], [[T0]]198; CHECK-NEXT:    [[T2:%.*]] = mul nsw i32 [[T0]], [[T1]]199; CHECK-NEXT:    [[T3:%.*]] = sub nsw i32 [[X]], [[T2]]200; CHECK-NEXT:    [[T4:%.*]] = sdiv i32 [[T3]], [[Y]]201; CHECK-NEXT:    [[T5:%.*]] = mul nsw i32 [[T4]], [[Y]]202; CHECK-NEXT:    [[T6:%.*]] = sub nsw i32 [[T3]], [[T5]]203; CHECK-NEXT:    ret i32 [[T6]]204;205  %t0 = mul nsw i32 %Z, %Y206  %t1 = sdiv i32 %X, %t0207  %t2 = mul nsw i32 %t0, %t1208  %t3 = sub nsw i32 %X, %t2209  %t4 = sdiv i32 %t3, %Y210  %t5 = mul nsw i32 %t4, %Y211  %t6 = sub nsw i32 %t3, %t5212  ret i32 %t6213}214 215; If the ops don't match, don't do anything: signedness.216 217define i32 @dont_hoist_udiv(i32 %a, i32 %b) {218; CHECK-LABEL: @dont_hoist_udiv(219; CHECK-NEXT:  entry:220; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[A:%.*]], [[B:%.*]]221; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[REM]], 42222; CHECK-NEXT:    br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]223; CHECK:       if:224; CHECK-NEXT:    [[DIV:%.*]] = udiv i32 [[A]], [[B]]225; CHECK-NEXT:    br label [[END]]226; CHECK:       end:227; CHECK-NEXT:    [[RET:%.*]] = phi i32 [ [[DIV]], [[IF]] ], [ 3, [[ENTRY:%.*]] ]228; CHECK-NEXT:    ret i32 [[RET]]229;230entry:231  %rem = srem i32 %a, %b232  %cmp = icmp eq i32 %rem, 42233  br i1 %cmp, label %if, label %end234 235if:236  %div = udiv i32 %a, %b237  br label %end238 239end:240  %ret = phi i32 [ %div, %if ], [ 3, %entry ]241  ret i32 %ret242}243 244; If the ops don't match, don't do anything: operation.245 246define i32 @dont_hoist_srem(i32 %a, i32 %b) {247; CHECK-LABEL: @dont_hoist_srem(248; CHECK-NEXT:  entry:249; CHECK-NEXT:    [[REM:%.*]] = urem i32 [[A:%.*]], [[B:%.*]]250; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[REM]], 42251; CHECK-NEXT:    br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]252; CHECK:       if:253; CHECK-NEXT:    [[REM2:%.*]] = srem i32 [[A]], [[B]]254; CHECK-NEXT:    br label [[END]]255; CHECK:       end:256; CHECK-NEXT:    [[RET:%.*]] = phi i32 [ [[REM2]], [[IF]] ], [ 3, [[ENTRY:%.*]] ]257; CHECK-NEXT:    ret i32 [[RET]]258;259entry:260  %rem = urem i32 %a, %b261  %cmp = icmp eq i32 %rem, 42262  br i1 %cmp, label %if, label %end263 264if:265  %rem2 = srem i32 %a, %b266  br label %end267 268end:269  %ret = phi i32 [ %rem2, %if ], [ 3, %entry ]270  ret i32 %ret271}272 273; If the ops don't match, don't do anything: operands.274 275define i32 @dont_hoist_sdiv(i32 %a, i32 %b, i32 %c) {276; CHECK-LABEL: @dont_hoist_sdiv(277; CHECK-NEXT:  entry:278; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[A:%.*]], [[B:%.*]]279; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[REM]], 42280; CHECK-NEXT:    br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]281; CHECK:       if:282; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[A]], [[C:%.*]]283; CHECK-NEXT:    br label [[END]]284; CHECK:       end:285; CHECK-NEXT:    [[RET:%.*]] = phi i32 [ [[DIV]], [[IF]] ], [ 3, [[ENTRY:%.*]] ]286; CHECK-NEXT:    ret i32 [[RET]]287;288entry:289  %rem = srem i32 %a, %b290  %cmp = icmp eq i32 %rem, 42291  br i1 %cmp, label %if, label %end292 293if:294  %div = sdiv i32 %a, %c295  br label %end296 297end:298  %ret = phi i32 [ %div, %if ], [ 3, %entry ]299  ret i32 %ret300}301 302; If the target doesn't have a unified div/rem op for the type, decompose rem in-place to mul+sub.303 304define i128 @dont_hoist_urem(i128 %a, i128 %b) {305; CHECK-LABEL: @dont_hoist_urem(306; CHECK-NEXT:  entry:307; CHECK-NEXT:    [[A_FROZEN:%.*]] = freeze i128 [[A:%.*]]308; CHECK-NEXT:    [[B_FROZEN:%.*]] = freeze i128 [[B:%.*]]309; CHECK-NEXT:    [[DIV:%.*]] = udiv i128 [[A_FROZEN]], [[B_FROZEN]]310; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i128 [[DIV]], 42311; CHECK-NEXT:    br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]312; CHECK:       if:313; CHECK-NEXT:    [[TMP0:%.*]] = mul i128 [[DIV]], [[B_FROZEN]]314; CHECK-NEXT:    [[REM_DECOMPOSED:%.*]] = sub i128 [[A_FROZEN]], [[TMP0]]315; CHECK-NEXT:    br label [[END]]316; CHECK:       end:317; CHECK-NEXT:    [[RET:%.*]] = phi i128 [ [[REM_DECOMPOSED]], [[IF]] ], [ 3, [[ENTRY:%.*]] ]318; CHECK-NEXT:    ret i128 [[RET]]319;320entry:321  %div = udiv i128 %a, %b322  %cmp = icmp eq i128 %div, 42323  br i1 %cmp, label %if, label %end324 325if:326  %rem = urem i128 %a, %b327  br label %end328 329end:330  %ret = phi i128 [ %rem, %if ], [ 3, %entry ]331  ret i128 %ret332}333 334; Do not hoist to the common predecessor block since we don't335; have a div-rem operation.336 337define i32 @no_domination(i1 %cmp, i32 %a, i32 %b) {338; CHECK-LABEL: @no_domination(339; CHECK-NEXT:  entry:340; CHECK-NEXT:    br i1 [[CMP:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]341; CHECK:       if:342; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[A:%.*]], [[B:%.*]]343; CHECK-NEXT:    br label [[END:%.*]]344; CHECK:       else:345; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[A]], [[B]]346; CHECK-NEXT:    br label [[END]]347; CHECK:       end:348; CHECK-NEXT:    [[RET:%.*]] = phi i32 [ [[DIV]], [[IF]] ], [ [[REM]], [[ELSE]] ]349; CHECK-NEXT:    ret i32 [[RET]]350;351entry:352  br i1 %cmp, label %if, label %else353 354if:355  %div = sdiv i32 %a, %b356  br label %end357 358else:359  %rem = srem i32 %a, %b360  br label %end361 362end:363  %ret = phi i32 [ %div, %if ], [ %rem, %else ]364  ret i32 %ret365}366 367