469 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; This tests the InstructionCombining optimization that reduces things like:5; %Y = sext i8 %X to i326; %C = icmp ult i32 %Y, 10247; to8; %C = i1 true9; It includes test cases for different constant values, signedness of the10; cast operands, and types of setCC operators. In all cases, the cast should11; be eliminated. In many cases the setCC is also eliminated based on the12; constant value and the range of the casted value.13;14 15define i1 @lt_signed_to_large_unsigned(i8 %SB) {16; CHECK-LABEL: @lt_signed_to_large_unsigned(17; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[SB:%.*]], -118; CHECK-NEXT: ret i1 [[C]]19;20 %Y = sext i8 %SB to i3221 %C = icmp ult i32 %Y, 102422 ret i1 %C23}24 25; PR28011 - https://llvm.org/bugs/show_bug.cgi?id=2801126; The above transform only applies to scalar integers; it shouldn't be attempted for constant expressions or vectors.27 28@a = common global ptr null29@b = common global [1 x i32] zeroinitializer30 31define i1 @PR28011(i16 %a) {32; CHECK-LABEL: @PR28011(33; CHECK-NEXT: [[CMP:%.*]] = icmp ne i16 [[A:%.*]], 134; CHECK-NEXT: ret i1 [[CMP]]35;36 %conv = sext i16 %a to i3237 %cmp2 = icmp ne ptr @b, @a38 %ext = zext i1 %cmp2 to i3239 %or = or i32 %ext, 140 %cmp = icmp ne i32 %conv, %or41 ret i1 %cmp42}43 44define <2 x i1> @lt_signed_to_large_unsigned_vec(<2 x i8> %SB) {45; CHECK-LABEL: @lt_signed_to_large_unsigned_vec(46; CHECK-NEXT: [[Y:%.*]] = sext <2 x i8> [[SB:%.*]] to <2 x i32>47; CHECK-NEXT: [[C:%.*]] = icmp ult <2 x i32> [[Y]], <i32 1024, i32 2>48; CHECK-NEXT: ret <2 x i1> [[C]]49;50 %Y = sext <2 x i8> %SB to <2 x i32>51 %C = icmp ult <2 x i32> %Y, <i32 1024, i32 2>52 ret <2 x i1> %C53}54 55define i1 @lt_signed_to_large_signed(i8 %SB) {56; CHECK-LABEL: @lt_signed_to_large_signed(57; CHECK-NEXT: ret i1 true58;59 %Y = sext i8 %SB to i3260 %C = icmp slt i32 %Y, 102461 ret i1 %C62}63 64define i1 @lt_signed_to_large_negative(i8 %SB) {65; CHECK-LABEL: @lt_signed_to_large_negative(66; CHECK-NEXT: ret i1 false67;68 %Y = sext i8 %SB to i3269 %C = icmp slt i32 %Y, -102470 ret i1 %C71}72 73define i1 @lt_signed_to_small_unsigned(i8 %SB) {74; CHECK-LABEL: @lt_signed_to_small_unsigned(75; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[SB:%.*]], 1776; CHECK-NEXT: ret i1 [[C]]77;78 %Y = sext i8 %SB to i3279 %C = icmp ult i32 %Y, 1780 ret i1 %C81}82 83define i1 @lt_signed_to_small_signed(i8 %SB) {84; CHECK-LABEL: @lt_signed_to_small_signed(85; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[SB:%.*]], 1786; CHECK-NEXT: ret i1 [[C]]87;88 %Y = sext i8 %SB to i3289 %C = icmp slt i32 %Y, 1790 ret i1 %C91}92define i1 @lt_signed_to_small_negative(i8 %SB) {93; CHECK-LABEL: @lt_signed_to_small_negative(94; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[SB:%.*]], -1795; CHECK-NEXT: ret i1 [[C]]96;97 %Y = sext i8 %SB to i3298 %C = icmp slt i32 %Y, -1799 ret i1 %C100}101 102define i1 @lt_unsigned_to_large_unsigned(i8 %SB) {103; CHECK-LABEL: @lt_unsigned_to_large_unsigned(104; CHECK-NEXT: ret i1 true105;106 %Y = zext i8 %SB to i32107 %C = icmp ult i32 %Y, 1024108 ret i1 %C109}110 111define i1 @lt_unsigned_to_large_signed(i8 %SB) {112; CHECK-LABEL: @lt_unsigned_to_large_signed(113; CHECK-NEXT: ret i1 true114;115 %Y = zext i8 %SB to i32116 %C = icmp slt i32 %Y, 1024117 ret i1 %C118}119 120define i1 @lt_unsigned_to_large_negative(i8 %SB) {121; CHECK-LABEL: @lt_unsigned_to_large_negative(122; CHECK-NEXT: ret i1 false123;124 %Y = zext i8 %SB to i32125 %C = icmp slt i32 %Y, -1024126 ret i1 %C127}128 129define i1 @lt_unsigned_to_small_unsigned(i8 %SB) {130; CHECK-LABEL: @lt_unsigned_to_small_unsigned(131; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[SB:%.*]], 17132; CHECK-NEXT: ret i1 [[C]]133;134 %Y = zext i8 %SB to i32135 %C = icmp ult i32 %Y, 17136 ret i1 %C137}138 139define i1 @lt_unsigned_to_small_signed(i8 %SB) {140; CHECK-LABEL: @lt_unsigned_to_small_signed(141; CHECK-NEXT: [[C:%.*]] = icmp ult i8 [[SB:%.*]], 17142; CHECK-NEXT: ret i1 [[C]]143;144 %Y = zext i8 %SB to i32145 %C = icmp slt i32 %Y, 17146 ret i1 %C147}148 149define i1 @lt_unsigned_to_small_negative(i8 %SB) {150; CHECK-LABEL: @lt_unsigned_to_small_negative(151; CHECK-NEXT: ret i1 false152;153 %Y = zext i8 %SB to i32154 %C = icmp slt i32 %Y, -17155 ret i1 %C156}157 158define i1 @gt_signed_to_large_unsigned(i8 %SB) {159; CHECK-LABEL: @gt_signed_to_large_unsigned(160; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[SB:%.*]], 0161; CHECK-NEXT: ret i1 [[C]]162;163 %Y = sext i8 %SB to i32164 %C = icmp ugt i32 %Y, 1024165 ret i1 %C166}167 168define i1 @gt_signed_to_large_signed(i8 %SB) {169; CHECK-LABEL: @gt_signed_to_large_signed(170; CHECK-NEXT: ret i1 false171;172 %Y = sext i8 %SB to i32173 %C = icmp sgt i32 %Y, 1024174 ret i1 %C175}176 177define i1 @gt_signed_to_large_negative(i8 %SB) {178; CHECK-LABEL: @gt_signed_to_large_negative(179; CHECK-NEXT: ret i1 true180;181 %Y = sext i8 %SB to i32182 %C = icmp sgt i32 %Y, -1024183 ret i1 %C184}185 186define i1 @gt_signed_to_small_unsigned(i8 %SB) {187; CHECK-LABEL: @gt_signed_to_small_unsigned(188; CHECK-NEXT: [[C:%.*]] = icmp ugt i8 [[SB:%.*]], 17189; CHECK-NEXT: ret i1 [[C]]190;191 %Y = sext i8 %SB to i32192 %C = icmp ugt i32 %Y, 17193 ret i1 %C194}195 196define i1 @gt_signed_to_small_signed(i8 %SB) {197; CHECK-LABEL: @gt_signed_to_small_signed(198; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[SB:%.*]], 17199; CHECK-NEXT: ret i1 [[C]]200;201 %Y = sext i8 %SB to i32202 %C = icmp sgt i32 %Y, 17203 ret i1 %C204}205 206define i1 @gt_signed_to_small_negative(i8 %SB) {207; CHECK-LABEL: @gt_signed_to_small_negative(208; CHECK-NEXT: [[C:%.*]] = icmp sgt i8 [[SB:%.*]], -17209; CHECK-NEXT: ret i1 [[C]]210;211 %Y = sext i8 %SB to i32212 %C = icmp sgt i32 %Y, -17213 ret i1 %C214}215 216define i1 @gt_unsigned_to_large_unsigned(i8 %SB) {217; CHECK-LABEL: @gt_unsigned_to_large_unsigned(218; CHECK-NEXT: ret i1 false219;220 %Y = zext i8 %SB to i32221 %C = icmp ugt i32 %Y, 1024222 ret i1 %C223}224 225define i1 @gt_unsigned_to_large_signed(i8 %SB) {226; CHECK-LABEL: @gt_unsigned_to_large_signed(227; CHECK-NEXT: ret i1 false228;229 %Y = zext i8 %SB to i32230 %C = icmp sgt i32 %Y, 1024231 ret i1 %C232}233 234define i1 @gt_unsigned_to_large_negative(i8 %SB) {235; CHECK-LABEL: @gt_unsigned_to_large_negative(236; CHECK-NEXT: ret i1 true237;238 %Y = zext i8 %SB to i32239 %C = icmp sgt i32 %Y, -1024240 ret i1 %C241}242 243define i1 @gt_unsigned_to_small_unsigned(i8 %SB) {244; CHECK-LABEL: @gt_unsigned_to_small_unsigned(245; CHECK-NEXT: [[C:%.*]] = icmp ugt i8 [[SB:%.*]], 17246; CHECK-NEXT: ret i1 [[C]]247;248 %Y = zext i8 %SB to i32249 %C = icmp ugt i32 %Y, 17250 ret i1 %C251}252 253define i1 @gt_unsigned_to_small_signed(i8 %SB) {254; CHECK-LABEL: @gt_unsigned_to_small_signed(255; CHECK-NEXT: [[C:%.*]] = icmp ugt i8 [[SB:%.*]], 17256; CHECK-NEXT: ret i1 [[C]]257;258 %Y = zext i8 %SB to i32259 %C = icmp sgt i32 %Y, 17260 ret i1 %C261}262 263define i1 @gt_unsigned_to_small_negative(i8 %SB) {264; CHECK-LABEL: @gt_unsigned_to_small_negative(265; CHECK-NEXT: ret i1 true266;267 %Y = zext i8 %SB to i32268 %C = icmp sgt i32 %Y, -17269 ret i1 %C270}271 272define i1 @different_size_zext_zext_ugt(i7 %x, i4 %y) {273; CHECK-LABEL: @different_size_zext_zext_ugt(274; CHECK-NEXT: [[TMP1:%.*]] = zext i4 [[Y:%.*]] to i7275; CHECK-NEXT: [[R:%.*]] = icmp ugt i7 [[X:%.*]], [[TMP1]]276; CHECK-NEXT: ret i1 [[R]]277;278 %zx = zext i7 %x to i25279 %zy = zext i4 %y to i25280 %r = icmp ugt i25 %zx, %zy281 ret i1 %r282}283 284define <2 x i1> @different_size_zext_zext_ugt_commute(<2 x i4> %x, <2 x i7> %y) {285; CHECK-LABEL: @different_size_zext_zext_ugt_commute(286; CHECK-NEXT: [[TMP1:%.*]] = zext <2 x i4> [[X:%.*]] to <2 x i7>287; CHECK-NEXT: [[R:%.*]] = icmp ult <2 x i7> [[Y:%.*]], [[TMP1]]288; CHECK-NEXT: ret <2 x i1> [[R]]289;290 %zx = zext <2 x i4> %x to <2 x i25>291 %zy = zext <2 x i7> %y to <2 x i25>292 %r = icmp ugt <2 x i25> %zx, %zy293 ret <2 x i1> %r294}295 296define i1 @different_size_zext_zext_ult(i4 %x, i7 %y) {297; CHECK-LABEL: @different_size_zext_zext_ult(298; CHECK-NEXT: [[TMP1:%.*]] = zext i4 [[X:%.*]] to i7299; CHECK-NEXT: [[R:%.*]] = icmp ugt i7 [[Y:%.*]], [[TMP1]]300; CHECK-NEXT: ret i1 [[R]]301;302 %zx = zext i4 %x to i25303 %zy = zext i7 %y to i25304 %r = icmp ult i25 %zx, %zy305 ret i1 %r306}307 308define i1 @different_size_zext_zext_eq(i4 %x, i7 %y) {309; CHECK-LABEL: @different_size_zext_zext_eq(310; CHECK-NEXT: [[TMP1:%.*]] = zext i4 [[X:%.*]] to i7311; CHECK-NEXT: [[R:%.*]] = icmp eq i7 [[Y:%.*]], [[TMP1]]312; CHECK-NEXT: ret i1 [[R]]313;314 %zx = zext i4 %x to i25315 %zy = zext i7 %y to i25316 %r = icmp eq i25 %zx, %zy317 ret i1 %r318}319 320define i1 @different_size_zext_zext_ne_commute(i7 %x, i4 %y) {321; CHECK-LABEL: @different_size_zext_zext_ne_commute(322; CHECK-NEXT: [[TMP1:%.*]] = zext i4 [[Y:%.*]] to i7323; CHECK-NEXT: [[R:%.*]] = icmp ne i7 [[X:%.*]], [[TMP1]]324; CHECK-NEXT: ret i1 [[R]]325;326 %zx = zext i7 %x to i25327 %zy = zext i4 %y to i25328 %r = icmp ne i25 %zx, %zy329 ret i1 %r330}331 332define i1 @different_size_zext_zext_slt(i7 %x, i4 %y) {333; CHECK-LABEL: @different_size_zext_zext_slt(334; CHECK-NEXT: [[TMP1:%.*]] = zext i4 [[Y:%.*]] to i7335; CHECK-NEXT: [[R:%.*]] = icmp ult i7 [[X:%.*]], [[TMP1]]336; CHECK-NEXT: ret i1 [[R]]337;338 %zx = zext i7 %x to i25339 %zy = zext i4 %y to i25340 %r = icmp slt i25 %zx, %zy341 ret i1 %r342}343 344define i1 @different_size_zext_zext_sgt(i7 %x, i4 %y) {345; CHECK-LABEL: @different_size_zext_zext_sgt(346; CHECK-NEXT: [[TMP1:%.*]] = zext i4 [[Y:%.*]] to i7347; CHECK-NEXT: [[R:%.*]] = icmp ugt i7 [[X:%.*]], [[TMP1]]348; CHECK-NEXT: ret i1 [[R]]349;350 %zx = zext i7 %x to i25351 %zy = zext i4 %y to i25352 %r = icmp sgt i25 %zx, %zy353 ret i1 %r354}355 356define i1 @different_size_sext_sext_sgt(i7 %x, i4 %y) {357; CHECK-LABEL: @different_size_sext_sext_sgt(358; CHECK-NEXT: [[TMP1:%.*]] = sext i4 [[Y:%.*]] to i7359; CHECK-NEXT: [[R:%.*]] = icmp sgt i7 [[X:%.*]], [[TMP1]]360; CHECK-NEXT: ret i1 [[R]]361;362 %sx = sext i7 %x to i25363 %sy = sext i4 %y to i25364 %r = icmp sgt i25 %sx, %sy365 ret i1 %r366}367 368define i1 @different_size_sext_sext_sle(i7 %x, i4 %y) {369; CHECK-LABEL: @different_size_sext_sext_sle(370; CHECK-NEXT: [[TMP1:%.*]] = sext i4 [[Y:%.*]] to i7371; CHECK-NEXT: [[R:%.*]] = icmp sle i7 [[X:%.*]], [[TMP1]]372; CHECK-NEXT: ret i1 [[R]]373;374 %sx = sext i7 %x to i25375 %sy = sext i4 %y to i25376 %r = icmp sle i25 %sx, %sy377 ret i1 %r378}379 380define i1 @different_size_sext_sext_eq(i7 %x, i4 %y) {381; CHECK-LABEL: @different_size_sext_sext_eq(382; CHECK-NEXT: [[TMP1:%.*]] = sext i4 [[Y:%.*]] to i7383; CHECK-NEXT: [[R:%.*]] = icmp eq i7 [[X:%.*]], [[TMP1]]384; CHECK-NEXT: ret i1 [[R]]385;386 %sx = sext i7 %x to i25387 %sy = sext i4 %y to i25388 %r = icmp eq i25 %sx, %sy389 ret i1 %r390}391 392define i1 @different_size_sext_sext_ule(i7 %x, i4 %y) {393; CHECK-LABEL: @different_size_sext_sext_ule(394; CHECK-NEXT: [[TMP1:%.*]] = sext i4 [[Y:%.*]] to i7395; CHECK-NEXT: [[R:%.*]] = icmp ule i7 [[X:%.*]], [[TMP1]]396; CHECK-NEXT: ret i1 [[R]]397;398 %sx = sext i7 %x to i25399 %sy = sext i4 %y to i25400 %r = icmp ule i25 %sx, %sy401 ret i1 %r402}403 404; TODO: This can be reduced.405 406define i1 @different_size_sext_zext_ne(i7 %x, i4 %y) {407; CHECK-LABEL: @different_size_sext_zext_ne(408; CHECK-NEXT: [[SX:%.*]] = sext i7 [[X:%.*]] to i25409; CHECK-NEXT: [[ZY:%.*]] = zext i4 [[Y:%.*]] to i25410; CHECK-NEXT: [[R:%.*]] = icmp ne i25 [[SX]], [[ZY]]411; CHECK-NEXT: ret i1 [[R]]412;413 %sx = sext i7 %x to i25414 %zy = zext i4 %y to i25415 %r = icmp ne i25 %sx, %zy416 ret i1 %r417}418 419declare void @use(i25)420 421define i1 @different_size_sext_sext_ule_extra_use1(i7 %x, i4 %y) {422; CHECK-LABEL: @different_size_sext_sext_ule_extra_use1(423; CHECK-NEXT: [[SY:%.*]] = sext i4 [[Y:%.*]] to i25424; CHECK-NEXT: call void @use(i25 [[SY]])425; CHECK-NEXT: [[TMP1:%.*]] = sext i4 [[Y]] to i7426; CHECK-NEXT: [[R:%.*]] = icmp ule i7 [[X:%.*]], [[TMP1]]427; CHECK-NEXT: ret i1 [[R]]428;429 %sx = sext i7 %x to i25430 %sy = sext i4 %y to i25431 call void @use(i25 %sy)432 %r = icmp ule i25 %sx, %sy433 ret i1 %r434}435 436define i1 @different_size_sext_sext_ule_extra_use2(i7 %x, i4 %y) {437; CHECK-LABEL: @different_size_sext_sext_ule_extra_use2(438; CHECK-NEXT: [[SX:%.*]] = sext i7 [[X:%.*]] to i25439; CHECK-NEXT: call void @use(i25 [[SX]])440; CHECK-NEXT: [[TMP1:%.*]] = sext i4 [[Y:%.*]] to i7441; CHECK-NEXT: [[R:%.*]] = icmp ule i7 [[X]], [[TMP1]]442; CHECK-NEXT: ret i1 [[R]]443;444 %sx = sext i7 %x to i25445 call void @use(i25 %sx)446 %sy = sext i4 %y to i25447 %r = icmp ule i25 %sx, %sy448 ret i1 %r449}450 451; Negative test - extra uses on both casts is too much.452 453define i1 @different_size_sext_sext_ule_extra_use3(i7 %x, i4 %y) {454; CHECK-LABEL: @different_size_sext_sext_ule_extra_use3(455; CHECK-NEXT: [[SX:%.*]] = sext i7 [[X:%.*]] to i25456; CHECK-NEXT: call void @use(i25 [[SX]])457; CHECK-NEXT: [[SY:%.*]] = sext i4 [[Y:%.*]] to i25458; CHECK-NEXT: call void @use(i25 [[SY]])459; CHECK-NEXT: [[R:%.*]] = icmp ule i25 [[SX]], [[SY]]460; CHECK-NEXT: ret i1 [[R]]461;462 %sx = sext i7 %x to i25463 call void @use(i25 %sx)464 %sy = sext i4 %y to i25465 call void @use(i25 %sy)466 %r = icmp ule i25 %sx, %sy467 ret i1 %r468}469