brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.5 KiB · d12cebe Raw
364 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; If we have a relational comparison with a constant, and said comparison is5; used in a select, and there is a constant in select, see if we can make6; those constants match.7 8; We can't ever get non-canonical scalar predicates.9 10; Likewise, while we can get non-canonical vector predicates, there must be an11; extra use on that `icmp`, which precludes the fold from happening.12 13;------------------------------------------------------------------------------;14; Canonical scalar predicates15;------------------------------------------------------------------------------;16 17!0 = !{!"branch_weights", i32 2000, i32 1}18 19define i32 @p0_ult_65536(i32 %x, i32 %y) {20; CHECK-LABEL: @p0_ult_65536(21; CHECK-NEXT:    [[T_INV:%.*]] = icmp ugt i32 [[X:%.*]], 6553522; CHECK-NEXT:    [[R:%.*]] = select i1 [[T_INV]], i32 65535, i32 [[Y:%.*]], !prof [[PROF0:![0-9]+]]23; CHECK-NEXT:    ret i32 [[R]]24;25  %t = icmp ult i32 %x, 6553626  %r = select i1 %t, i32 %y, i32 65535, !prof !027  ret i32 %r28}29define i32 @p1_ugt(i32 %x, i32 %y) {30; CHECK-LABEL: @p1_ugt(31; CHECK-NEXT:    [[T_INV:%.*]] = icmp ult i32 [[X:%.*]], 6553532; CHECK-NEXT:    [[R:%.*]] = select i1 [[T_INV]], i32 65535, i32 [[Y:%.*]]33; CHECK-NEXT:    ret i32 [[R]]34;35  %t = icmp ugt i32 %x, 6553436  %r = select i1 %t, i32 %y, i32 6553537  ret i32 %r38}39define i32 @p2_slt_65536(i32 %x, i32 %y) {40; CHECK-LABEL: @p2_slt_65536(41; CHECK-NEXT:    [[T_INV:%.*]] = icmp sgt i32 [[X:%.*]], 6553542; CHECK-NEXT:    [[R:%.*]] = select i1 [[T_INV]], i32 65535, i32 [[Y:%.*]]43; CHECK-NEXT:    ret i32 [[R]]44;45  %t = icmp slt i32 %x, 6553646  %r = select i1 %t, i32 %y, i32 6553547  ret i32 %r48}49define i32 @p3_sgt(i32 %x, i32 %y) {50; CHECK-LABEL: @p3_sgt(51; CHECK-NEXT:    [[T_INV:%.*]] = icmp slt i32 [[X:%.*]], 6553552; CHECK-NEXT:    [[R:%.*]] = select i1 [[T_INV]], i32 65535, i32 [[Y:%.*]]53; CHECK-NEXT:    ret i32 [[R]]54;55  %t = icmp sgt i32 %x, 6553456  %r = select i1 %t, i32 %y, i32 6553557  ret i32 %r58}59 60;------------------------------------------------------------------------------;61; Vectors62;------------------------------------------------------------------------------;63 64define <2 x i32> @p4_vec_splat_ult_65536(<2 x i32> %x, <2 x i32> %y) {65; CHECK-LABEL: @p4_vec_splat_ult_65536(66; CHECK-NEXT:    [[T_INV:%.*]] = icmp ugt <2 x i32> [[X:%.*]], splat (i32 65535)67; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[T_INV]], <2 x i32> splat (i32 65535), <2 x i32> [[Y:%.*]]68; CHECK-NEXT:    ret <2 x i32> [[R]]69;70  %t = icmp ult <2 x i32> %x, <i32 65536, i32 65536>71  %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 65535>72  ret <2 x i32> %r73}74define <2 x i32> @p5_vec_splat_ugt(<2 x i32> %x, <2 x i32> %y) {75; CHECK-LABEL: @p5_vec_splat_ugt(76; CHECK-NEXT:    [[T_INV:%.*]] = icmp ult <2 x i32> [[X:%.*]], splat (i32 65535)77; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[T_INV]], <2 x i32> splat (i32 65535), <2 x i32> [[Y:%.*]]78; CHECK-NEXT:    ret <2 x i32> [[R]]79;80  %t = icmp ugt <2 x i32> %x, <i32 65534, i32 65534>81  %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 65535>82  ret <2 x i32> %r83}84define <2 x i32> @p6_vec_splat_slt_65536(<2 x i32> %x, <2 x i32> %y) {85; CHECK-LABEL: @p6_vec_splat_slt_65536(86; CHECK-NEXT:    [[T_INV:%.*]] = icmp sgt <2 x i32> [[X:%.*]], splat (i32 65535)87; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[T_INV]], <2 x i32> splat (i32 65535), <2 x i32> [[Y:%.*]]88; CHECK-NEXT:    ret <2 x i32> [[R]]89;90  %t = icmp slt <2 x i32> %x, <i32 65536, i32 65536>91  %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 65535>92  ret <2 x i32> %r93}94define <2 x i32> @p7_vec_splat_sgt(<2 x i32> %x, <2 x i32> %y) {95; CHECK-LABEL: @p7_vec_splat_sgt(96; CHECK-NEXT:    [[T_INV:%.*]] = icmp slt <2 x i32> [[X:%.*]], splat (i32 65535)97; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[T_INV]], <2 x i32> splat (i32 65535), <2 x i32> [[Y:%.*]]98; CHECK-NEXT:    ret <2 x i32> [[R]]99;100  %t = icmp sgt <2 x i32> %x, <i32 65534, i32 65534>101  %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 65535>102  ret <2 x i32> %r103}104 105; Vectors with poison106 107define <2 x i32> @p8_vec_nonsplat_poison0(<2 x i32> %x, <2 x i32> %y) {108; CHECK-LABEL: @p8_vec_nonsplat_poison0(109; CHECK-NEXT:    [[T_INV:%.*]] = icmp ugt <2 x i32> [[X:%.*]], splat (i32 65535)110; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[T_INV]], <2 x i32> splat (i32 65535), <2 x i32> [[Y:%.*]]111; CHECK-NEXT:    ret <2 x i32> [[R]]112;113  %t = icmp ult <2 x i32> %x, <i32 65536, i32 poison>114  %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 65535>115  ret <2 x i32> %r116}117define <2 x i32> @p9_vec_nonsplat_poison1(<2 x i32> %x, <2 x i32> %y) {118; CHECK-LABEL: @p9_vec_nonsplat_poison1(119; CHECK-NEXT:    [[T_INV:%.*]] = icmp ugt <2 x i32> [[X:%.*]], splat (i32 65535)120; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[T_INV]], <2 x i32> <i32 65535, i32 poison>, <2 x i32> [[Y:%.*]]121; CHECK-NEXT:    ret <2 x i32> [[R]]122;123  %t = icmp ult <2 x i32> %x, <i32 65536, i32 65536>124  %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 poison>125  ret <2 x i32> %r126}127define <2 x i32> @p10_vec_nonsplat_poison2(<2 x i32> %x, <2 x i32> %y) {128; CHECK-LABEL: @p10_vec_nonsplat_poison2(129; CHECK-NEXT:    [[T_INV:%.*]] = icmp ugt <2 x i32> [[X:%.*]], splat (i32 65535)130; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[T_INV]], <2 x i32> <i32 65535, i32 poison>, <2 x i32> [[Y:%.*]]131; CHECK-NEXT:    ret <2 x i32> [[R]]132;133  %t = icmp ult <2 x i32> %x, <i32 65536, i32 poison>134  %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 poison>135  ret <2 x i32> %r136}137 138; Non-splat vectors139 140define <2 x i32> @p11_vec_nonsplat(<2 x i32> %x, <2 x i32> %y) {141; CHECK-LABEL: @p11_vec_nonsplat(142; CHECK-NEXT:    [[T_INV:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 65535, i32 32767>143; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[T_INV]], <2 x i32> <i32 65535, i32 32767>, <2 x i32> [[Y:%.*]]144; CHECK-NEXT:    ret <2 x i32> [[R]]145;146  %t = icmp ult <2 x i32> %x, <i32 65536, i32 32768>147  %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 32767>148  ret <2 x i32> %r149}150 151;------------------------------------------------------------------------------;152; Extra uses prevent the fold.153;------------------------------------------------------------------------------;154 155declare void @use1(i1)156 157define i32 @n12_extrause(i32 %x, i32 %y) {158; CHECK-LABEL: @n12_extrause(159; CHECK-NEXT:    [[T:%.*]] = icmp ult i32 [[X:%.*]], 65536160; CHECK-NEXT:    call void @use1(i1 [[T]])161; CHECK-NEXT:    [[R:%.*]] = select i1 [[T]], i32 [[Y:%.*]], i32 65535162; CHECK-NEXT:    ret i32 [[R]]163;164  %t = icmp ult i32 %x, 65536165  call void @use1(i1 %t)166  %r = select i1 %t, i32 %y, i32 65535167  ret i32 %r168}169 170;------------------------------------------------------------------------------;171; Commutativity172;------------------------------------------------------------------------------;173 174; We don't care if the constant in select is true value or false value175define i32 @p13_commutativity0(i32 %x, i32 %y) {176; CHECK-LABEL: @p13_commutativity0(177; CHECK-NEXT:    [[T_INV:%.*]] = icmp ugt i32 [[X:%.*]], 65535178; CHECK-NEXT:    [[R:%.*]] = select i1 [[T_INV]], i32 [[Y:%.*]], i32 65535179; CHECK-NEXT:    ret i32 [[R]]180;181  %t = icmp ult i32 %x, 65536182  %r = select i1 %t, i32 65535, i32 %y183  ret i32 %r184}185 186; Which means, if both possibilities are constants, we must check both of them.187define i32 @p14_commutativity1(i32 %x, i32 %y) {188; CHECK-LABEL: @p14_commutativity1(189; CHECK-NEXT:    [[T_INV:%.*]] = icmp ugt i32 [[X:%.*]], 65535190; CHECK-NEXT:    [[R:%.*]] = select i1 [[T_INV]], i32 42, i32 65535191; CHECK-NEXT:    ret i32 [[R]]192;193  %t = icmp ult i32 %x, 65536194  %r = select i1 %t, i32 65535, i32 42195  ret i32 %r196}197define i32 @p15_commutativity2(i32 %x, i32 %y) {198; CHECK-LABEL: @p15_commutativity2(199; CHECK-NEXT:    [[T_INV:%.*]] = icmp ugt i32 [[X:%.*]], 65535200; CHECK-NEXT:    [[R:%.*]] = select i1 [[T_INV]], i32 65535, i32 42201; CHECK-NEXT:    ret i32 [[R]]202;203  %t = icmp ult i32 %x, 65536204  %r = select i1 %t, i32 42, i32 65535205  ret i32 %r206}207 208;------------------------------------------------------------------------------;209; Negative tests210;------------------------------------------------------------------------------;211 212; For vectors, make sure we handle edge cases correctly213define <2 x i32> @n17_ult_zero(<2 x i32> %x, <2 x i32> %y) {214; CHECK-LABEL: @n17_ult_zero(215; CHECK-NEXT:    [[T:%.*]] = icmp ult <2 x i32> [[X:%.*]], <i32 65536, i32 0>216; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[T]], <2 x i32> [[Y:%.*]], <2 x i32> <i32 65535, i32 -1>217; CHECK-NEXT:    ret <2 x i32> [[R]]218;219  %t = icmp ult <2 x i32> %x, <i32 65536, i32 0>220  %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 -1>221  ret <2 x i32> %r222}223define <2 x i32> @n18_ugt_allones(<2 x i32> %x, <2 x i32> %y) {224; CHECK-LABEL: @n18_ugt_allones(225; CHECK-NEXT:    [[T:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 65534, i32 -1>226; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[T]], <2 x i32> [[Y:%.*]], <2 x i32> <i32 65535, i32 0>227; CHECK-NEXT:    ret <2 x i32> [[R]]228;229  %t = icmp ugt <2 x i32> %x, <i32 65534, i32 -1>230  %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 0>231  ret <2 x i32> %r232}233define <2 x i32> @n19_slt_int_min(<2 x i32> %x, <2 x i32> %y) {234; CHECK-LABEL: @n19_slt_int_min(235; CHECK-NEXT:    [[T:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 65536, i32 -2147483648>236; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[T]], <2 x i32> [[Y:%.*]], <2 x i32> <i32 65535, i32 2147483647>237; CHECK-NEXT:    ret <2 x i32> [[R]]238;239  %t = icmp slt <2 x i32> %x, <i32 65536, i32 -2147483648>240  %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 2147483647>241  ret <2 x i32> %r242}243define <2 x i32> @n20_sgt_int_max(<2 x i32> %x, <2 x i32> %y) {244; CHECK-LABEL: @n20_sgt_int_max(245; CHECK-NEXT:    [[T:%.*]] = icmp sgt <2 x i32> [[X:%.*]], <i32 65534, i32 2147483647>246; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[T]], <2 x i32> [[Y:%.*]], <2 x i32> <i32 65535, i32 -2147483648>247; CHECK-NEXT:    ret <2 x i32> [[R]]248;249  %t = icmp sgt <2 x i32> %x, <i32 65534, i32 2147483647>250  %r = select <2 x i1> %t, <2 x i32> %y, <2 x i32> <i32 65535, i32 -2147483648>251  ret <2 x i32> %r252}253 254; We don't do anything for non-relational comparisons.255define i32 @n21_equality(i32 %x, i32 %y) {256; CHECK-LABEL: @n21_equality(257; CHECK-NEXT:    [[T:%.*]] = icmp eq i32 [[X:%.*]], -2147483648258; CHECK-NEXT:    [[R:%.*]] = select i1 [[T]], i32 2147483647, i32 [[Y:%.*]]259; CHECK-NEXT:    ret i32 [[R]]260;261  %t = icmp eq i32 %x, -2147483648262  %r = select i1 %t, i32 2147483647, i32 %y263  ret i32 %r264}265 266; There is nothing special about sign-bit-tests, we can fold them.267define i32 @t22_sign_check(i32 %x, i32 %y) {268; CHECK-LABEL: @t22_sign_check(269; CHECK-NEXT:    [[T_INV:%.*]] = icmp sgt i32 [[X:%.*]], -1270; CHECK-NEXT:    [[R:%.*]] = select i1 [[T_INV]], i32 [[Y:%.*]], i32 -1271; CHECK-NEXT:    ret i32 [[R]]272;273  %t = icmp slt i32 %x, 0274  %r = select i1 %t, i32 -1, i32 %y275  ret i32 %r276}277define i32 @t22_sign_check2(i32 %x, i32 %y) {278; CHECK-LABEL: @t22_sign_check2(279; CHECK-NEXT:    [[T_INV:%.*]] = icmp slt i32 [[X:%.*]], 0280; CHECK-NEXT:    [[R:%.*]] = select i1 [[T_INV]], i32 [[Y:%.*]], i32 0281; CHECK-NEXT:    ret i32 [[R]]282;283  %t = icmp sgt i32 %x, -1284  %r = select i1 %t, i32 0, i32 %y285  ret i32 %r286}287 288; If the types don't match we currently don't do anything.289define i32 @n23_type_mismatch(i64 %x, i32 %y) {290; CHECK-LABEL: @n23_type_mismatch(291; CHECK-NEXT:    [[T:%.*]] = icmp ult i64 [[X:%.*]], 65536292; CHECK-NEXT:    [[R:%.*]] = select i1 [[T]], i32 [[Y:%.*]], i32 65535293; CHECK-NEXT:    ret i32 [[R]]294;295  %t = icmp ult i64 %x, 65536296  %r = select i1 %t, i32 %y, i32 65535297  ret i32 %r298}299 300; Don't do wrong tranform301define i32 @n24_ult_65534(i32 %x, i32 %y) {302; CHECK-LABEL: @n24_ult_65534(303; CHECK-NEXT:    [[T:%.*]] = icmp ult i32 [[X:%.*]], 65534304; CHECK-NEXT:    [[R:%.*]] = select i1 [[T]], i32 [[Y:%.*]], i32 65535305; CHECK-NEXT:    ret i32 [[R]]306;307  %t = icmp ult i32 %x, 65534308  %r = select i1 %t, i32 %y, i32 65535309  ret i32 %r310}311 312; If we already have a match, it's good enough.313define i32 @n25_all_good0(i32 %x, i32 %y) {314; CHECK-LABEL: @n25_all_good0(315; CHECK-NEXT:    [[T:%.*]] = icmp ult i32 [[X:%.*]], 65536316; CHECK-NEXT:    [[R:%.*]] = select i1 [[T]], i32 65535, i32 65536317; CHECK-NEXT:    ret i32 [[R]]318;319  %t = icmp ult i32 %x, 65536320  %r = select i1 %t, i32 65535, i32 65536321  ret i32 %r322}323define i32 @n26_all_good1(i32 %x, i32 %y) {324; CHECK-LABEL: @n26_all_good1(325; CHECK-NEXT:    [[T:%.*]] = icmp ult i32 [[X:%.*]], 65536326; CHECK-NEXT:    [[R:%.*]] = select i1 [[T]], i32 65536, i32 65535327; CHECK-NEXT:    ret i32 [[R]]328;329  %t = icmp ult i32 %x, 65536330  %r = select i1 %t, i32 65536, i32 65535331  ret i32 %r332}333 334; https://llvm.org/PR52684335; Do not infinite loop by opposing 'ult' canonicalization.336 337define i32 @ult_inf_loop(i32 %x) {338; CHECK-LABEL: @ult_inf_loop(339; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[X:%.*]], -1340; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[ADD]], 2341; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], i32 1, i32 -3342; CHECK-NEXT:    ret i32 [[SEL]]343;344  %add = add i32 %x, -1345  %cmp = icmp ult i32 %add, 2346  %sel = select i1 %cmp, i32 1, i32 -3347  ret i32 %sel348}349 350define <2 x i32> @ult_inf_loop_vec(<2 x i32> %x) {351; CHECK-LABEL: @ult_inf_loop_vec(352; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], splat (i32 38)353; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[TMP1]], splat (i32 -4)354; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i32> splat (i32 -5), <2 x i32> splat (i32 3)355; CHECK-NEXT:    ret <2 x i32> [[SEL]]356;357  %add = add <2 x i32> %x, <i32 42, i32 42>358  %cmp = icmp ugt <2 x i32> %add, <i32 3, i32 3>359  %sel = select <2 x i1> %cmp, <2 x i32> <i32 -5, i32 -5>, <2 x i32> <i32 3, i32 3>360  ret <2 x i32> %sel361}362 363; CHECK: !0 = !{!"branch_weights", i32 1, i32 2000}364