290 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 32; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; Tests for foldAndOrOfICmpEqConstantAndICmp5; https://github.com/llvm/llvm-project/issues/637496 7; ==============================================================================8; (icmp eq X, C) | (icmp ult Other, (X - C)) -> (icmp ule Other, (X - (C + 1)))9; (icmp ne X, C) & (icmp uge Other, (X - C)) -> (icmp ugt Other, (X - (C + 1)))10; ==============================================================================11 12; ==============================================================================13; Basic tests14; ==============================================================================15define i1 @eq_basic(i8 %x, i8 %y) {16; CHECK-LABEL: define i1 @eq_basic(17; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {18; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X]], -119; CHECK-NEXT: [[OR:%.*]] = icmp uge i8 [[TMP1]], [[Y]]20; CHECK-NEXT: ret i1 [[OR]]21;22 %c1 = icmp eq i8 %x, 023 %c2 = icmp ugt i8 %x, %y24 %or = or i1 %c1, %c225 ret i1 %or26}27 28define i1 @ne_basic_equal_5(i8 %x, i8 %y) {29; CHECK-LABEL: define i1 @ne_basic_equal_5(30; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {31; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X]], -632; CHECK-NEXT: [[AND:%.*]] = icmp ult i8 [[TMP1]], [[Y]]33; CHECK-NEXT: ret i1 [[AND]]34;35 %sub = add i8 %x, -536 %c1 = icmp ne i8 %x, 537 %c2 = icmp ule i8 %sub, %y38 %and = and i1 %c1, %c239 ret i1 %and40}41 42define i1 @eq_basic_equal_minus_1(i8 %x, i8 %y) {43; CHECK-LABEL: define i1 @eq_basic_equal_minus_1(44; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {45; CHECK-NEXT: [[OR:%.*]] = icmp uge i8 [[X]], [[Y]]46; CHECK-NEXT: ret i1 [[OR]]47;48 %add = add i8 %x, 149 %c1 = icmp eq i8 %x, -150 %c2 = icmp ugt i8 %add, %y51 %or = or i1 %c1, %c252 ret i1 %or53}54 55define i1 @ne_basic_equal_minus_7(i8 %x, i8 %y) {56; CHECK-LABEL: define i1 @ne_basic_equal_minus_7(57; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {58; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X]], 659; CHECK-NEXT: [[AND:%.*]] = icmp ult i8 [[TMP1]], [[Y]]60; CHECK-NEXT: ret i1 [[AND]]61;62 %add = add i8 %x, 763 %c1 = icmp ne i8 %x, -764 %c2 = icmp ule i8 %add, %y65 %and = and i1 %c1, %c266 ret i1 %and67}68 69define i1 @eq_basic_unequal(i8 %x, i8 %y) {70; CHECK-LABEL: define i1 @eq_basic_unequal(71; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {72; CHECK-NEXT: [[SUB:%.*]] = add i8 [[X]], -573; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X]], 674; CHECK-NEXT: [[C2:%.*]] = icmp ugt i8 [[SUB]], [[Y]]75; CHECK-NEXT: [[OR:%.*]] = or i1 [[C1]], [[C2]]76; CHECK-NEXT: ret i1 [[OR]]77;78 %sub = add i8 %x, -579 %c1 = icmp eq i8 %x, 680 %c2 = icmp ugt i8 %sub, %y81 %or = or i1 %c1, %c282 ret i1 %or83}84 85define i1 @ne_basic_unequal(i8 %x, i8 %y) {86; CHECK-LABEL: define i1 @ne_basic_unequal(87; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {88; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X]], 789; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 [[X]], -490; CHECK-NEXT: [[C2:%.*]] = icmp ule i8 [[ADD]], [[Y]]91; CHECK-NEXT: [[AND:%.*]] = and i1 [[C1]], [[C2]]92; CHECK-NEXT: ret i1 [[AND]]93;94 %add = add i8 %x, 795 %c1 = icmp ne i8 %x, -496 %c2 = icmp ule i8 %add, %y97 %and = and i1 %c1, %c298 ret i1 %and99}100 101; ==============================================================================102; Tests with multiple uses103; ==============================================================================104define i1 @eq_multi_c1(i8 %x, i8 %y) {105; CHECK-LABEL: define i1 @eq_multi_c1(106; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {107; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X]], 0108; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X]], -1109; CHECK-NEXT: [[OR:%.*]] = icmp uge i8 [[TMP1]], [[Y]]110; CHECK-NEXT: call void @use(i1 [[C1]])111; CHECK-NEXT: ret i1 [[OR]]112;113 %c1 = icmp eq i8 %x, 0114 %c2 = icmp ugt i8 %x, %y115 %or = or i1 %c1, %c2116 call void @use(i1 %c1)117 ret i1 %or118}119 120define i1 @ne_multi_c2(i8 %x, i8 %y) {121; CHECK-LABEL: define i1 @ne_multi_c2(122; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {123; CHECK-NEXT: [[C2:%.*]] = icmp ule i8 [[X]], [[Y]]124; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X]], -1125; CHECK-NEXT: [[AND:%.*]] = icmp ult i8 [[TMP1]], [[Y]]126; CHECK-NEXT: call void @use(i1 [[C2]])127; CHECK-NEXT: ret i1 [[AND]]128;129 %c1 = icmp ne i8 %x, 0130 %c2 = icmp ule i8 %x, %y131 %and = and i1 %c1, %c2132 call void @use(i1 %c2)133 ret i1 %and134}135 136; ==============================================================================137; Tests with vector types138; ==============================================================================139define <2 x i1> @eq_vector(<2 x i8> %x, <2 x i8> %y) {140; CHECK-LABEL: define <2 x i1> @eq_vector(141; CHECK-SAME: <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {142; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[X]], splat (i8 -1)143; CHECK-NEXT: [[OR:%.*]] = icmp uge <2 x i8> [[TMP1]], [[Y]]144; CHECK-NEXT: ret <2 x i1> [[OR]]145;146 %c1 = icmp eq <2 x i8> %x, <i8 0, i8 0>147 %c2 = icmp ugt <2 x i8> %x, %y148 %or = or <2 x i1> %c1, %c2149 ret <2 x i1> %or150}151 152define <2 x i1> @ne_vector_equal_5(<2 x i8> %x, <2 x i8> %y) {153; CHECK-LABEL: define <2 x i1> @ne_vector_equal_5(154; CHECK-SAME: <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {155; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[X]], splat (i8 -6)156; CHECK-NEXT: [[AND:%.*]] = icmp ult <2 x i8> [[TMP1]], [[Y]]157; CHECK-NEXT: ret <2 x i1> [[AND]]158;159 %sub = add <2 x i8> %x, <i8 -5, i8 -5>160 %c1 = icmp ne <2 x i8> %x, <i8 5, i8 5>161 %c2 = icmp ule <2 x i8> %sub, %y162 %and = and <2 x i1> %c1, %c2163 ret <2 x i1> %and164}165 166define <2 x i1> @eq_vector_equal_minus_1(<2 x i8> %x, <2 x i8> %y) {167; CHECK-LABEL: define <2 x i1> @eq_vector_equal_minus_1(168; CHECK-SAME: <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {169; CHECK-NEXT: [[OR:%.*]] = icmp uge <2 x i8> [[X]], [[Y]]170; CHECK-NEXT: ret <2 x i1> [[OR]]171;172 %add = add <2 x i8> %x, <i8 1, i8 1>173 %c1 = icmp eq <2 x i8> %x, <i8 -1, i8 -1>174 %c2 = icmp ugt <2 x i8> %add, %y175 %or = or <2 x i1> %c1, %c2176 ret <2 x i1> %or177}178 179define <2 x i1> @ne_vector_equal_minus_7(<2 x i8> %x, <2 x i8> %y) {180; CHECK-LABEL: define <2 x i1> @ne_vector_equal_minus_7(181; CHECK-SAME: <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {182; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[X]], splat (i8 6)183; CHECK-NEXT: [[AND:%.*]] = icmp ult <2 x i8> [[TMP1]], [[Y]]184; CHECK-NEXT: ret <2 x i1> [[AND]]185;186 %add = add <2 x i8> %x, <i8 7, i8 7>187 %c1 = icmp ne <2 x i8> %x, <i8 -7, i8 -7>188 %c2 = icmp ule <2 x i8> %add, %y189 %and = and <2 x i1> %c1, %c2190 ret <2 x i1> %and191}192 193define <2 x i1> @eq_vector_unequal1(<2 x i8> %x, <2 x i8> %y) {194; CHECK-LABEL: define <2 x i1> @eq_vector_unequal1(195; CHECK-SAME: <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {196; CHECK-NEXT: [[SUB:%.*]] = add <2 x i8> [[X]], splat (i8 -5)197; CHECK-NEXT: [[C1:%.*]] = icmp eq <2 x i8> [[X]], splat (i8 2)198; CHECK-NEXT: [[C2:%.*]] = icmp ugt <2 x i8> [[SUB]], [[Y]]199; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[C1]], [[C2]]200; CHECK-NEXT: ret <2 x i1> [[OR]]201;202 %sub = add <2 x i8> %x, <i8 -5, i8 -5>203 %c1 = icmp eq <2 x i8> %x, <i8 2, i8 2>204 %c2 = icmp ugt <2 x i8> %sub, %y205 %or = or <2 x i1> %c1, %c2206 ret <2 x i1> %or207}208 209define <2 x i1> @ne_vector_unequal2(<2 x i8> %x, <2 x i8> %y) {210; CHECK-LABEL: define <2 x i1> @ne_vector_unequal2(211; CHECK-SAME: <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {212; CHECK-NEXT: [[ADD:%.*]] = add <2 x i8> [[X]], splat (i8 7)213; CHECK-NEXT: [[C1:%.*]] = icmp ne <2 x i8> [[X]], splat (i8 -3)214; CHECK-NEXT: [[C2:%.*]] = icmp ule <2 x i8> [[ADD]], [[Y]]215; CHECK-NEXT: [[AND:%.*]] = and <2 x i1> [[C1]], [[C2]]216; CHECK-NEXT: ret <2 x i1> [[AND]]217;218 %add = add <2 x i8> %x, <i8 7, i8 7>219 %c1 = icmp ne <2 x i8> %x, <i8 -3, i8 -3>220 %c2 = icmp ule <2 x i8> %add, %y221 %and = and <2 x i1> %c1, %c2222 ret <2 x i1> %and223}224 225; ==============================================================================226; Tests with poison227; ==============================================================================228define <2 x i1> @eq_vector_poison_icmp(<2 x i8> %x, <2 x i8> %y) {229; CHECK-LABEL: define <2 x i1> @eq_vector_poison_icmp(230; CHECK-SAME: <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {231; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[X]], splat (i8 -6)232; CHECK-NEXT: [[OR:%.*]] = icmp uge <2 x i8> [[TMP1]], [[Y]]233; CHECK-NEXT: ret <2 x i1> [[OR]]234;235 %sub = add <2 x i8> %x, <i8 -5, i8 -5>236 %c1 = icmp eq <2 x i8> %x, <i8 5, i8 poison>237 %c2 = icmp ugt <2 x i8> %sub, %y238 %or = or <2 x i1> %c1, %c2239 ret <2 x i1> %or240}241 242define <2 x i1> @eq_vector_poison_add(<2 x i8> %x, <2 x i8> %y) {243; CHECK-LABEL: define <2 x i1> @eq_vector_poison_add(244; CHECK-SAME: <2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {245; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[X]], splat (i8 -6)246; CHECK-NEXT: [[OR:%.*]] = icmp uge <2 x i8> [[TMP1]], [[Y]]247; CHECK-NEXT: ret <2 x i1> [[OR]]248;249 %sub = add <2 x i8> %x, <i8 -5, i8 poison>250 %c1 = icmp eq <2 x i8> %x, <i8 5, i8 5>251 %c2 = icmp ugt <2 x i8> %sub, %y252 %or = or <2 x i1> %c1, %c2253 ret <2 x i1> %or254}255 256; ==============================================================================257; Tests with values commuted258; ==============================================================================259define i1 @eq_commuted(i8 %x, i8 %py) {260; CHECK-LABEL: define i1 @eq_commuted(261; CHECK-SAME: i8 [[X:%.*]], i8 [[PY:%.*]]) {262; CHECK-NEXT: [[Y:%.*]] = sdiv i8 43, [[PY]]263; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X]], -1264; CHECK-NEXT: [[OR:%.*]] = icmp uge i8 [[TMP1]], [[Y]]265; CHECK-NEXT: ret i1 [[OR]]266;267 %y = sdiv i8 43, %py ; thwart complexity-based canonicalization268 %c1 = icmp eq i8 %x, 0269 %c2 = icmp ult i8 %y, %x270 %or = or i1 %c1, %c2271 ret i1 %or272}273 274define i1 @ne_commuted_equal_minus_1(i8 %x, i8 %py) {275; CHECK-LABEL: define i1 @ne_commuted_equal_minus_1(276; CHECK-SAME: i8 [[X:%.*]], i8 [[PY:%.*]]) {277; CHECK-NEXT: [[Y:%.*]] = sdiv i8 42, [[PY]]278; CHECK-NEXT: [[AND:%.*]] = icmp ult i8 [[X]], [[Y]]279; CHECK-NEXT: ret i1 [[AND]]280;281 %y = sdiv i8 42, %py ; thwart complexity-based canonicalization282 %add = add i8 %x, 1283 %c1 = icmp ne i8 %x, -1284 %c2 = icmp uge i8 %y, %add285 %and = and i1 %c1, %c2286 ret i1 %and287}288 289declare void @use(i1)290