brintos

brintos / llvm-project-archived public Read only

0
0
Text · 12.0 KiB · 7dff78e Raw
378 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; It is a miscompile in most of these tests if we5; execute div/rem without freezing the potentially6; poison condition value.7 8define i5 @sdiv_common_divisor(i1 %b, i5 %x, i5 %y, i5 %z) {9; CHECK-LABEL: @sdiv_common_divisor(10; CHECK-NEXT:    [[TMP1:%.*]] = freeze i1 [[B:%.*]]11; CHECK-NEXT:    [[SEL_V:%.*]] = select i1 [[TMP1]], i5 [[Z:%.*]], i5 [[Y:%.*]]12; CHECK-NEXT:    [[SEL:%.*]] = sdiv i5 [[SEL_V]], [[X:%.*]]13; CHECK-NEXT:    ret i5 [[SEL]]14;15  %r1 = sdiv i5 %y, %x16  %r2 = sdiv i5 %z, %x17  %sel = select i1 %b, i5 %r2, i5 %r118  ret i5 %sel19}20 21define i5 @srem_common_divisor(i1 %b, i5 %x, i5 %y, i5 %z) {22; CHECK-LABEL: @srem_common_divisor(23; CHECK-NEXT:    [[TMP1:%.*]] = freeze i1 [[B:%.*]]24; CHECK-NEXT:    [[SEL_V:%.*]] = select i1 [[TMP1]], i5 [[Z:%.*]], i5 [[Y:%.*]]25; CHECK-NEXT:    [[SEL:%.*]] = srem i5 [[SEL_V]], [[X:%.*]]26; CHECK-NEXT:    ret i5 [[SEL]]27;28  %r1 = srem i5 %y, %x29  %r2 = srem i5 %z, %x30  %sel = select i1 %b, i5 %r2, i5 %r131  ret i5 %sel32}33 34; This is ok without freeze because UB can only happen with x==0,35; and that occurs in the original code.36 37define i5 @udiv_common_divisor(i1 %b, i5 %x, i5 %y, i5 %z) {38; CHECK-LABEL: @udiv_common_divisor(39; CHECK-NEXT:    [[SEL_V:%.*]] = select i1 [[B:%.*]], i5 [[Z:%.*]], i5 [[Y:%.*]]40; CHECK-NEXT:    [[SEL:%.*]] = udiv i5 [[SEL_V]], [[X:%.*]]41; CHECK-NEXT:    ret i5 [[SEL]]42;43  %r1 = udiv i5 %y, %x44  %r2 = udiv i5 %z, %x45  %sel = select i1 %b, i5 %r2, i5 %r146  ret i5 %sel47}48 49; This is ok without freeze because UB can only happen with x==0,50; and that occurs in the original code.51 52define i5 @urem_common_divisor(i1 %b, i5 %x, i5 %y, i5 %z) {53; CHECK-LABEL: @urem_common_divisor(54; CHECK-NEXT:    [[SEL_V:%.*]] = select i1 [[B:%.*]], i5 [[Z:%.*]], i5 [[Y:%.*]]55; CHECK-NEXT:    [[SEL:%.*]] = urem i5 [[SEL_V]], [[X:%.*]]56; CHECK-NEXT:    ret i5 [[SEL]]57;58  %r1 = urem i5 %y, %x59  %r2 = urem i5 %z, %x60  %sel = select i1 %b, i5 %r2, i5 %r161  ret i5 %sel62}63 64define i5 @sdiv_common_dividend(i1 %b, i5 %x, i5 %y, i5 %z) {65; CHECK-LABEL: @sdiv_common_dividend(66; CHECK-NEXT:    [[TMP1:%.*]] = freeze i1 [[B:%.*]]67; CHECK-NEXT:    [[SEL_V:%.*]] = select i1 [[TMP1]], i5 [[Z:%.*]], i5 [[Y:%.*]]68; CHECK-NEXT:    [[SEL:%.*]] = sdiv i5 [[X:%.*]], [[SEL_V]]69; CHECK-NEXT:    ret i5 [[SEL]]70;71  %r1 = sdiv i5 %x, %y72  %r2 = sdiv i5 %x, %z73  %sel = select i1 %b, i5 %r2, i5 %r174  ret i5 %sel75}76 77define i5 @srem_common_dividend(i1 %b, i5 %x, i5 %y, i5 %z) {78; CHECK-LABEL: @srem_common_dividend(79; CHECK-NEXT:    [[TMP1:%.*]] = freeze i1 [[B:%.*]]80; CHECK-NEXT:    [[SEL_V:%.*]] = select i1 [[TMP1]], i5 [[Z:%.*]], i5 [[Y:%.*]]81; CHECK-NEXT:    [[SEL:%.*]] = srem i5 [[X:%.*]], [[SEL_V]]82; CHECK-NEXT:    ret i5 [[SEL]]83;84  %r1 = srem i5 %x, %y85  %r2 = srem i5 %x, %z86  %sel = select i1 %b, i5 %r2, i5 %r187  ret i5 %sel88}89 90define i5 @udiv_common_dividend(i1 %b, i5 %x, i5 %y, i5 %z) {91; CHECK-LABEL: @udiv_common_dividend(92; CHECK-NEXT:    [[TMP1:%.*]] = freeze i1 [[B:%.*]]93; CHECK-NEXT:    [[SEL_V:%.*]] = select i1 [[TMP1]], i5 [[Z:%.*]], i5 [[Y:%.*]]94; CHECK-NEXT:    [[SEL:%.*]] = udiv i5 [[X:%.*]], [[SEL_V]]95; CHECK-NEXT:    ret i5 [[SEL]]96;97  %r1 = udiv i5 %x, %y98  %r2 = udiv i5 %x, %z99  %sel = select i1 %b, i5 %r2, i5 %r1100  ret i5 %sel101}102 103define i5 @urem_common_dividend(i1 %b, i5 %x, i5 %y, i5 %z) {104; CHECK-LABEL: @urem_common_dividend(105; CHECK-NEXT:    [[TMP1:%.*]] = freeze i1 [[B:%.*]]106; CHECK-NEXT:    [[SEL_V:%.*]] = select i1 [[TMP1]], i5 [[Z:%.*]], i5 [[Y:%.*]]107; CHECK-NEXT:    [[SEL:%.*]] = urem i5 [[X:%.*]], [[SEL_V]]108; CHECK-NEXT:    ret i5 [[SEL]]109;110  %r1 = urem i5 %x, %y111  %r2 = urem i5 %x, %z112  %sel = select i1 %b, i5 %r2, i5 %r1113  ret i5 %sel114}115 116; Repeat the above tests, but guarantee that the select117; condition is not poison via argument attribute. That118; makes it safe to execute the select before div/rem119; without needing to freeze the condition.120 121define i5 @sdiv_common_divisor_defined_cond(i1 noundef %b, i5 %x, i5 %y, i5 %z) {122; CHECK-LABEL: @sdiv_common_divisor_defined_cond(123; CHECK-NEXT:    [[SEL_V:%.*]] = select i1 [[B:%.*]], i5 [[Z:%.*]], i5 [[Y:%.*]]124; CHECK-NEXT:    [[SEL:%.*]] = sdiv i5 [[SEL_V]], [[X:%.*]]125; CHECK-NEXT:    ret i5 [[SEL]]126;127  %r1 = sdiv i5 %y, %x128  %r2 = sdiv i5 %z, %x129  %sel = select i1 %b, i5 %r2, i5 %r1130  ret i5 %sel131}132 133define i5 @srem_common_divisor_defined_cond(i1 noundef %b, i5 %x, i5 %y, i5 %z) {134; CHECK-LABEL: @srem_common_divisor_defined_cond(135; CHECK-NEXT:    [[SEL_V:%.*]] = select i1 [[B:%.*]], i5 [[Z:%.*]], i5 [[Y:%.*]]136; CHECK-NEXT:    [[SEL:%.*]] = srem i5 [[SEL_V]], [[X:%.*]]137; CHECK-NEXT:    ret i5 [[SEL]]138;139  %r1 = srem i5 %y, %x140  %r2 = srem i5 %z, %x141  %sel = select i1 %b, i5 %r2, i5 %r1142  ret i5 %sel143}144 145define i5 @udiv_common_divisor_defined_cond(i1 noundef %b, i5 %x, i5 %y, i5 %z) {146; CHECK-LABEL: @udiv_common_divisor_defined_cond(147; CHECK-NEXT:    [[SEL_V:%.*]] = select i1 [[B:%.*]], i5 [[Z:%.*]], i5 [[Y:%.*]]148; CHECK-NEXT:    [[SEL:%.*]] = udiv i5 [[SEL_V]], [[X:%.*]]149; CHECK-NEXT:    ret i5 [[SEL]]150;151  %r1 = udiv i5 %y, %x152  %r2 = udiv i5 %z, %x153  %sel = select i1 %b, i5 %r2, i5 %r1154  ret i5 %sel155}156 157define i5 @urem_common_divisor_defined_cond(i1 noundef %b, i5 %x, i5 %y, i5 %z) {158; CHECK-LABEL: @urem_common_divisor_defined_cond(159; CHECK-NEXT:    [[SEL_V:%.*]] = select i1 [[B:%.*]], i5 [[Z:%.*]], i5 [[Y:%.*]]160; CHECK-NEXT:    [[SEL:%.*]] = urem i5 [[SEL_V]], [[X:%.*]]161; CHECK-NEXT:    ret i5 [[SEL]]162;163  %r1 = urem i5 %y, %x164  %r2 = urem i5 %z, %x165  %sel = select i1 %b, i5 %r2, i5 %r1166  ret i5 %sel167}168 169define i5 @sdiv_common_dividend_defined_cond(i1 noundef %b, i5 %x, i5 %y, i5 %z) {170; CHECK-LABEL: @sdiv_common_dividend_defined_cond(171; CHECK-NEXT:    [[SEL_V:%.*]] = select i1 [[B:%.*]], i5 [[Z:%.*]], i5 [[Y:%.*]]172; CHECK-NEXT:    [[SEL:%.*]] = sdiv i5 [[X:%.*]], [[SEL_V]]173; CHECK-NEXT:    ret i5 [[SEL]]174;175  %r1 = sdiv i5 %x, %y176  %r2 = sdiv i5 %x, %z177  %sel = select i1 %b, i5 %r2, i5 %r1178  ret i5 %sel179}180 181define i5 @srem_common_dividend_defined_cond(i1 noundef %b, i5 %x, i5 %y, i5 %z) {182; CHECK-LABEL: @srem_common_dividend_defined_cond(183; CHECK-NEXT:    [[SEL_V:%.*]] = select i1 [[B:%.*]], i5 [[Z:%.*]], i5 [[Y:%.*]]184; CHECK-NEXT:    [[SEL:%.*]] = srem i5 [[X:%.*]], [[SEL_V]]185; CHECK-NEXT:    ret i5 [[SEL]]186;187  %r1 = srem i5 %x, %y188  %r2 = srem i5 %x, %z189  %sel = select i1 %b, i5 %r2, i5 %r1190  ret i5 %sel191}192 193define i5 @udiv_common_dividend_defined_cond(i1 noundef %b, i5 %x, i5 %y, i5 %z) {194; CHECK-LABEL: @udiv_common_dividend_defined_cond(195; CHECK-NEXT:    [[SEL_V:%.*]] = select i1 [[B:%.*]], i5 [[Z:%.*]], i5 [[Y:%.*]]196; CHECK-NEXT:    [[SEL:%.*]] = udiv i5 [[X:%.*]], [[SEL_V]]197; CHECK-NEXT:    ret i5 [[SEL]]198;199  %r1 = udiv i5 %x, %y200  %r2 = udiv i5 %x, %z201  %sel = select i1 %b, i5 %r2, i5 %r1202  ret i5 %sel203}204 205define i5 @urem_common_dividend_defined_cond(i1 noundef %b, i5 %x, i5 %y, i5 %z) {206; CHECK-LABEL: @urem_common_dividend_defined_cond(207; CHECK-NEXT:    [[SEL_V:%.*]] = select i1 [[B:%.*]], i5 [[Z:%.*]], i5 [[Y:%.*]]208; CHECK-NEXT:    [[SEL:%.*]] = urem i5 [[X:%.*]], [[SEL_V]]209; CHECK-NEXT:    ret i5 [[SEL]]210;211  %r1 = urem i5 %x, %y212  %r2 = urem i5 %x, %z213  %sel = select i1 %b, i5 %r2, i5 %r1214  ret i5 %sel215}216 217define i32 @rem_euclid_1(i32 %0) {218; CHECK-LABEL: @rem_euclid_1(219; CHECK-NEXT:    [[SEL:%.*]] = and i32 [[TMP0:%.*]], 7220; CHECK-NEXT:    ret i32 [[SEL]]221;222  %rem = srem i32 %0, 8223  %cond = icmp slt i32 %rem, 0224  %add = add i32 %rem, 8225  %sel = select i1 %cond, i32 %add, i32 %rem226  ret i32 %sel227}228 229define i32 @rem_euclid_2(i32 %0) {230; CHECK-LABEL: @rem_euclid_2(231; CHECK-NEXT:    [[SEL:%.*]] = and i32 [[TMP0:%.*]], 7232; CHECK-NEXT:    ret i32 [[SEL]]233;234  %rem = srem i32 %0, 8235  %cond = icmp sgt i32 %rem, -1236  %add = add i32 %rem, 8237  %sel = select i1 %cond, i32 %rem, i32 %add238  ret i32 %sel239}240 241define i32 @rem_euclid_wrong_sign_test(i32 %0) {242; CHECK-LABEL: @rem_euclid_wrong_sign_test(243; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[TMP0:%.*]], 8244; CHECK-NEXT:    [[COND:%.*]] = icmp sgt i32 [[REM]], 0245; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[REM]], 8246; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND]], i32 [[ADD]], i32 [[REM]]247; CHECK-NEXT:    ret i32 [[SEL]]248;249  %rem = srem i32 %0, 8250  %cond = icmp sgt i32 %rem, 0251  %add = add i32 %rem, 8252  %sel = select i1 %cond, i32 %add, i32 %rem253  ret i32 %sel254}255 256define i32 @rem_euclid_add_different_const(i32 %0) {257; CHECK-LABEL: @rem_euclid_add_different_const(258; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[TMP0:%.*]], 8259; CHECK-NEXT:    [[COND:%.*]] = icmp slt i32 [[REM]], 0260; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[REM]], 9261; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND]], i32 [[ADD]], i32 [[REM]]262; CHECK-NEXT:    ret i32 [[SEL]]263;264  %rem = srem i32 %0, 8265  %cond = icmp slt i32 %rem, 0266  %add = add i32 %rem, 9267  %sel = select i1 %cond, i32 %add, i32 %rem268  ret i32 %sel269}270 271define i32 @rem_euclid_wrong_operands_select(i32 %0) {272; CHECK-LABEL: @rem_euclid_wrong_operands_select(273; CHECK-NEXT:    [[REM:%.*]] = srem i32 [[TMP0:%.*]], 8274; CHECK-NEXT:    [[COND:%.*]] = icmp slt i32 [[REM]], 0275; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[REM]], 8276; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND]], i32 [[REM]], i32 [[ADD]]277; CHECK-NEXT:    ret i32 [[SEL]]278;279  %rem = srem i32 %0, 8280  %cond = icmp slt i32 %rem, 0281  %add = add i32 %rem, 8282  %sel = select i1 %cond, i32 %rem, i32 %add283  ret i32 %sel284}285 286define <2 x i32> @rem_euclid_vec(<2 x i32> %0) {287; CHECK-LABEL: @rem_euclid_vec(288; CHECK-NEXT:    [[SEL:%.*]] = and <2 x i32> [[TMP0:%.*]], splat (i32 7)289; CHECK-NEXT:    ret <2 x i32> [[SEL]]290;291  %rem = srem <2 x i32> %0, <i32 8, i32 8>292  %cond = icmp slt <2 x i32> %rem, <i32 0, i32 0>293  %add = add <2 x i32> %rem, <i32 8, i32 8>294  %sel = select <2 x i1> %cond, <2 x i32> %add, <2 x i32> %rem295  ret <2 x i32> %sel296}297 298define i128 @rem_euclid_i128(i128 %0) {299; CHECK-LABEL: @rem_euclid_i128(300; CHECK-NEXT:    [[SEL:%.*]] = and i128 [[TMP0:%.*]], 7301; CHECK-NEXT:    ret i128 [[SEL]]302;303  %rem = srem i128 %0, 8304  %cond = icmp slt i128 %rem, 0305  %add = add i128 %rem, 8306  %sel = select i1 %cond, i128 %add, i128 %rem307  ret i128 %sel308}309 310define i8 @rem_euclid_non_const_pow2(i8 %0, i8 %1) {311; CHECK-LABEL: @rem_euclid_non_const_pow2(312; CHECK-NEXT:    [[NOTMASK:%.*]] = shl nsw i8 -1, [[TMP0:%.*]]313; CHECK-NEXT:    [[TMP3:%.*]] = xor i8 [[NOTMASK]], -1314; CHECK-NEXT:    [[SEL:%.*]] = and i8 [[TMP1:%.*]], [[TMP3]]315; CHECK-NEXT:    ret i8 [[SEL]]316;317  %pow2 = shl i8 1, %0318  %rem = srem i8 %1, %pow2319  %cond = icmp slt i8 %rem, 0320  %add = add i8 %rem, %pow2321  %sel = select i1 %cond, i8 %add, i8 %rem322  ret i8 %sel323}324 325define i8 @rem_euclid_non_const_pow2_commuted(i8 %0, i8 %1) {326; CHECK-LABEL: @rem_euclid_non_const_pow2_commuted(327; CHECK-NEXT:    [[NOTMASK:%.*]] = shl nsw i8 -1, [[TMP0:%.*]]328; CHECK-NEXT:    [[TMP3:%.*]] = xor i8 [[NOTMASK]], -1329; CHECK-NEXT:    [[SEL:%.*]] = and i8 [[TMP1:%.*]], [[TMP3]]330; CHECK-NEXT:    ret i8 [[SEL]]331;332  %pow2 = shl i8 1, %0333  %rem = srem i8 %1, %pow2334  %cond = icmp slt i8 %rem, 0335  %add = add i8 %pow2, %rem336  %sel = select i1 %cond, i8 %add, i8 %rem337  ret i8 %sel338}339 340define i32 @rem_euclid_pow2_true_arm_folded(i32 %n) {341; CHECK-LABEL: @rem_euclid_pow2_true_arm_folded(342; CHECK-NEXT:    [[RES:%.*]] = and i32 [[N:%.*]], 1343; CHECK-NEXT:    ret i32 [[RES]]344;345  %rem = srem i32 %n, 2346  %neg = icmp slt i32 %rem, 0347  %res = select i1 %neg, i32 1, i32 %rem348  ret i32 %res349}350 351define i32 @rem_euclid_pow2_false_arm_folded(i32 %n) {352; CHECK-LABEL: @rem_euclid_pow2_false_arm_folded(353; CHECK-NEXT:    [[RES:%.*]] = and i32 [[N:%.*]], 1354; CHECK-NEXT:    ret i32 [[RES]]355;356  %rem = srem i32 %n, 2357  %nonneg = icmp sge i32 %rem, 0358  %res = select i1 %nonneg, i32 %rem, i32 1359  ret i32 %res360}361 362define i8 @pr89516(i8 %n, i8 %x) {363; CHECK-LABEL: @pr89516(364; CHECK-NEXT:    [[COND:%.*]] = icmp slt i8 [[X:%.*]], 0365; CHECK-NEXT:    [[POW2:%.*]] = shl nuw i8 1, [[N:%.*]]366; CHECK-NEXT:    [[SREM:%.*]] = srem i8 1, [[POW2]]367; CHECK-NEXT:    [[ADD:%.*]] = select i1 [[COND]], i8 [[POW2]], i8 0368; CHECK-NEXT:    [[RES:%.*]] = add nuw i8 [[SREM]], [[ADD]]369; CHECK-NEXT:    ret i8 [[RES]]370;371  %cond = icmp slt i8 %x, 0372  %pow2 = shl nuw i8 1, %n373  %srem = srem i8 1, %pow2374  %add = add nuw i8 %srem, %pow2375  %res = select i1 %cond, i8 %add, i8 %srem376  ret i8 %res377}378