366 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt -S -passes=correlated-propagation < %s | FileCheck %s3 4define <2 x i1> @cmp1(<2 x i8> %a) {5; CHECK-LABEL: define <2 x i1> @cmp1(6; CHECK-SAME: <2 x i8> [[A:%.*]]) {7; CHECK-NEXT: [[ADD:%.*]] = add nuw <2 x i8> [[A]], splat (i8 1)8; CHECK-NEXT: ret <2 x i1> splat (i1 true)9;10 %add = add nuw <2 x i8> %a, splat (i8 1)11 %cmp = icmp ne <2 x i8> %add, zeroinitializer12 ret <2 x i1> %cmp13}14 15define <2 x i1> @cmp2(<2 x i8> %a) {16; CHECK-LABEL: define <2 x i1> @cmp2(17; CHECK-SAME: <2 x i8> [[A:%.*]]) {18; CHECK-NEXT: [[ADD:%.*]] = add nuw <2 x i8> [[A]], splat (i8 5)19; CHECK-NEXT: ret <2 x i1> splat (i1 true)20;21 %add = add nuw <2 x i8> %a, splat (i8 5)22 %cmp = icmp ugt <2 x i8> %add, splat (i8 2)23 ret <2 x i1> %cmp24}25 26define <2 x i1> @cmp_nonsplat(<2 x i8> %a) {27; CHECK-LABEL: define <2 x i1> @cmp_nonsplat(28; CHECK-SAME: <2 x i8> [[A:%.*]]) {29; CHECK-NEXT: [[ADD:%.*]] = add nuw <2 x i8> [[A]], <i8 4, i8 5>30; CHECK-NEXT: ret <2 x i1> splat (i1 true)31;32 %add = add nuw <2 x i8> %a, <i8 4, i8 5>33 %cmp = icmp ugt <2 x i8> %add, <i8 2, i8 3>34 ret <2 x i1> %cmp35}36 37; Handling this would require keeping track of ranges on a per-element basis.38define <2 x i1> @cmp_nonsplat_fail(<2 x i8> %a) {39; CHECK-LABEL: define <2 x i1> @cmp_nonsplat_fail(40; CHECK-SAME: <2 x i8> [[A:%.*]]) {41; CHECK-NEXT: [[ADD:%.*]] = add nuw <2 x i8> [[A]], <i8 3, i8 4>42; CHECK-NEXT: [[CMP:%.*]] = icmp ugt <2 x i8> [[ADD]], <i8 2, i8 3>43; CHECK-NEXT: ret <2 x i1> [[CMP]]44;45 %add = add nuw <2 x i8> %a, <i8 3, i8 4>46 %cmp = icmp ugt <2 x i8> %add, <i8 2, i8 3>47 ret <2 x i1> %cmp48}49 50define <2 x i1> @cmp_signedness(<2 x i8> %a) {51; CHECK-LABEL: define <2 x i1> @cmp_signedness(52; CHECK-SAME: <2 x i8> [[A:%.*]]) {53; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>54; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ult <2 x i16> [[ZEXT]], splat (i16 5)55; CHECK-NEXT: ret <2 x i1> [[CMP]]56;57 %zext = zext <2 x i8> %a to <2 x i16>58 %cmp = icmp slt <2 x i16> %zext, splat (i16 5)59 ret <2 x i1> %cmp60}61 62define <2 x i16> @infer_nowrap(<2 x i8> %a) {63; CHECK-LABEL: define range(i16 1, 257) <2 x i16> @infer_nowrap(64; CHECK-SAME: <2 x i8> [[A:%.*]]) {65; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>66; CHECK-NEXT: [[RES:%.*]] = add nuw nsw <2 x i16> [[ZEXT]], splat (i16 1)67; CHECK-NEXT: ret <2 x i16> [[RES]]68;69 %zext = zext <2 x i8> %a to <2 x i16>70 %res = add <2 x i16> %zext, splat (i16 1)71 ret <2 x i16> %res72}73 74define <2 x i16> @infer_nowrap_nonsplat(<2 x i8> %a) {75; CHECK-LABEL: define range(i16 1, 258) <2 x i16> @infer_nowrap_nonsplat(76; CHECK-SAME: <2 x i8> [[A:%.*]]) {77; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>78; CHECK-NEXT: [[RES:%.*]] = add nuw nsw <2 x i16> [[ZEXT]], <i16 1, i16 2>79; CHECK-NEXT: ret <2 x i16> [[RES]]80;81 %zext = zext <2 x i8> %a to <2 x i16>82 %res = add <2 x i16> %zext, <i16 1, i16 2>83 ret <2 x i16> %res84}85 86define <vscale x 2 x i16> @infer_nowrap_scalable(<vscale x 2 x i8> %a) {87; CHECK-LABEL: define range(i16 1, 257) <vscale x 2 x i16> @infer_nowrap_scalable(88; CHECK-SAME: <vscale x 2 x i8> [[A:%.*]]) {89; CHECK-NEXT: [[ZEXT:%.*]] = zext <vscale x 2 x i8> [[A]] to <vscale x 2 x i16>90; CHECK-NEXT: [[RES:%.*]] = add nuw nsw <vscale x 2 x i16> [[ZEXT]], splat (i16 1)91; CHECK-NEXT: ret <vscale x 2 x i16> [[RES]]92;93 %zext = zext <vscale x 2 x i8> %a to <vscale x 2 x i16>94 %res = add <vscale x 2 x i16> %zext, splat (i16 1)95 ret <vscale x 2 x i16> %res96}97 98define <2 x i16> @infer_nowrap_poison(<2 x i8> %a) {99; CHECK-LABEL: define range(i16 1, 257) <2 x i16> @infer_nowrap_poison(100; CHECK-SAME: <2 x i8> [[A:%.*]]) {101; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>102; CHECK-NEXT: [[RES:%.*]] = add nuw nsw <2 x i16> [[ZEXT]], <i16 1, i16 poison>103; CHECK-NEXT: ret <2 x i16> [[RES]]104;105 %zext = zext <2 x i8> %a to <2 x i16>106 %res = add <2 x i16> %zext, <i16 1, i16 poison>107 ret <2 x i16> %res108}109 110define <2 x i16> @infer_nowrap_nonsplat_nsw_only(<2 x i8> %a) {111; CHECK-LABEL: define range(i16 -1, 257) <2 x i16> @infer_nowrap_nonsplat_nsw_only(112; CHECK-SAME: <2 x i8> [[A:%.*]]) {113; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>114; CHECK-NEXT: [[RES:%.*]] = add nsw <2 x i16> [[ZEXT]], <i16 1, i16 -1>115; CHECK-NEXT: ret <2 x i16> [[RES]]116;117 %zext = zext <2 x i8> %a to <2 x i16>118 %res = add <2 x i16> %zext, <i16 1, i16 -1>119 ret <2 x i16> %res120}121 122define <2 x i16> @abs(<2 x i8> %a) {123; CHECK-LABEL: define range(i16 0, 256) <2 x i16> @abs(124; CHECK-SAME: <2 x i8> [[A:%.*]]) {125; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>126; CHECK-NEXT: ret <2 x i16> [[ZEXT]]127;128 %zext = zext <2 x i8> %a to <2 x i16>129 %res = call <2 x i16> @llvm.abs(<2 x i16> %zext, i1 false)130 ret <2 x i16> %res131}132 133define <2 x i16> @saturating(<2 x i8> %a) {134; CHECK-LABEL: define range(i16 1, 257) <2 x i16> @saturating(135; CHECK-SAME: <2 x i8> [[A:%.*]]) {136; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>137; CHECK-NEXT: [[RES:%.*]] = add nuw nsw <2 x i16> [[ZEXT]], splat (i16 1)138; CHECK-NEXT: ret <2 x i16> [[RES]]139;140 %zext = zext <2 x i8> %a to <2 x i16>141 %res = call <2 x i16> @llvm.uadd.sat(<2 x i16> %zext, <2 x i16> splat (i16 1))142 ret <2 x i16> %res143}144 145define {<2 x i16>, <2 x i1>} @with_overflow(<2 x i8> %a) {146; CHECK-LABEL: define { <2 x i16>, <2 x i1> } @with_overflow(147; CHECK-SAME: <2 x i8> [[A:%.*]]) {148; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>149; CHECK-NEXT: [[RES1:%.*]] = add nuw nsw <2 x i16> [[ZEXT]], splat (i16 1)150; CHECK-NEXT: [[RES:%.*]] = insertvalue { <2 x i16>, <2 x i1> } { <2 x i16> poison, <2 x i1> zeroinitializer }, <2 x i16> [[RES1]], 0151; CHECK-NEXT: ret { <2 x i16>, <2 x i1> } [[RES]]152;153 %zext = zext <2 x i8> %a to <2 x i16>154 %res = call {<2 x i16>, <2 x i1>} @llvm.uadd.with.overflow(<2 x i16> %zext, <2 x i16> splat (i16 1))155 ret {<2 x i16>, <2 x i1>} %res156}157 158define <2 x i16> @srem1(<2 x i8> %a) {159; CHECK-LABEL: define range(i16 0, 42) <2 x i16> @srem1(160; CHECK-SAME: <2 x i8> [[A:%.*]]) {161; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>162; CHECK-NEXT: [[RES1_LHS_TRUNC:%.*]] = trunc <2 x i16> [[ZEXT]] to <2 x i8>163; CHECK-NEXT: [[RES12:%.*]] = urem <2 x i8> [[RES1_LHS_TRUNC]], splat (i8 42)164; CHECK-NEXT: [[RES:%.*]] = zext <2 x i8> [[RES12]] to <2 x i16>165; CHECK-NEXT: ret <2 x i16> [[RES]]166;167 %zext = zext <2 x i8> %a to <2 x i16>168 %res = srem <2 x i16> %zext, splat (i16 42)169 ret <2 x i16> %res170}171 172define <2 x i16> @srem2(<2 x i8> %a) {173; CHECK-LABEL: define range(i16 -41, 42) <2 x i16> @srem2(174; CHECK-SAME: <2 x i8> [[A:%.*]]) {175; CHECK-NEXT: [[ZEXT:%.*]] = sext <2 x i8> [[A]] to <2 x i16>176; CHECK-NEXT: [[RES_LHS_TRUNC:%.*]] = trunc <2 x i16> [[ZEXT]] to <2 x i8>177; CHECK-NEXT: [[RES1:%.*]] = srem <2 x i8> [[RES_LHS_TRUNC]], splat (i8 42)178; CHECK-NEXT: [[RES:%.*]] = sext <2 x i8> [[RES1]] to <2 x i16>179; CHECK-NEXT: ret <2 x i16> [[RES]]180;181 %zext = sext <2 x i8> %a to <2 x i16>182 %res = srem <2 x i16> %zext, splat (i16 42)183 ret <2 x i16> %res184}185 186define <2 x i16> @ashr(<2 x i8> %a) {187; CHECK-LABEL: define range(i16 0, 128) <2 x i16> @ashr(188; CHECK-SAME: <2 x i8> [[A:%.*]]) {189; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>190; CHECK-NEXT: [[RES:%.*]] = lshr <2 x i16> [[ZEXT]], splat (i16 1)191; CHECK-NEXT: ret <2 x i16> [[RES]]192;193 %zext = zext <2 x i8> %a to <2 x i16>194 %res = ashr <2 x i16> %zext, splat (i16 1)195 ret <2 x i16> %res196}197 198define <2 x i32> @sext(<2 x i8> %a) {199; CHECK-LABEL: define range(i32 0, 256) <2 x i32> @sext(200; CHECK-SAME: <2 x i8> [[A:%.*]]) {201; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>202; CHECK-NEXT: [[RES:%.*]] = zext nneg <2 x i16> [[ZEXT]] to <2 x i32>203; CHECK-NEXT: ret <2 x i32> [[RES]]204;205 %zext = zext <2 x i8> %a to <2 x i16>206 %res = sext <2 x i16> %zext to <2 x i32>207 ret <2 x i32> %res208}209 210define <2 x float> @sitofp(<2 x i8> %a) {211; CHECK-LABEL: define <2 x float> @sitofp(212; CHECK-SAME: <2 x i8> [[A:%.*]]) {213; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>214; CHECK-NEXT: [[RES:%.*]] = uitofp nneg <2 x i16> [[ZEXT]] to <2 x float>215; CHECK-NEXT: ret <2 x float> [[RES]]216;217 %zext = zext <2 x i8> %a to <2 x i16>218 %res = sitofp <2 x i16> %zext to <2 x float>219 ret <2 x float> %res220}221 222define <2 x i16> @and(<2 x i8> %a) {223; CHECK-LABEL: define range(i16 0, 256) <2 x i16> @and(224; CHECK-SAME: <2 x i8> [[A:%.*]]) {225; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>226; CHECK-NEXT: ret <2 x i16> [[ZEXT]]227;228 %zext = zext <2 x i8> %a to <2 x i16>229 %res = and <2 x i16> %zext, splat (i16 u0xff)230 ret <2 x i16> %res231}232 233define <2 x i16> @and_with_poison(<2 x i8> %a) {234; CHECK-LABEL: define range(i16 0, 256) <2 x i16> @and_with_poison(235; CHECK-SAME: <2 x i8> [[A:%.*]]) {236; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>237; CHECK-NEXT: ret <2 x i16> [[ZEXT]]238;239 %zext = zext <2 x i8> %a to <2 x i16>240 %res = and <2 x i16> %zext, <i16 u0xff, i16 poison>241 ret <2 x i16> %res242}243 244define <4 x i64> @issue_97674_getConstantOnEdge(i1 %cond) {245; CHECK-LABEL: define range(i64 0, 2) <4 x i64> @issue_97674_getConstantOnEdge(246; CHECK-SAME: i1 [[COND:%.*]]) {247; CHECK-NEXT: [[ENTRY:.*]]:248; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]249; CHECK: [[IF_THEN]]:250; CHECK-NEXT: [[FOLDS:%.*]] = add nuw nsw <4 x i64> zeroinitializer, splat (i64 1)251; CHECK-NEXT: br label %[[IF_END]]252; CHECK: [[IF_END]]:253; CHECK-NEXT: [[R:%.*]] = phi <4 x i64> [ splat (i64 1), %[[IF_THEN]] ], [ zeroinitializer, %[[ENTRY]] ]254; CHECK-NEXT: ret <4 x i64> [[R]]255;256entry:257 br i1 %cond, label %if.then, label %if.end258 259if.then:260 %folds = add <4 x i64> zeroinitializer, <i64 1, i64 1, i64 1, i64 1>261 br label %if.end262 263if.end:264 %r = phi <4 x i64> [ %folds, %if.then ], [ zeroinitializer, %entry ]265 ret <4 x i64> %r266}267 268define <4 x i64> @issue_97674_getConstant() {269; CHECK-LABEL: define <4 x i64> @issue_97674_getConstant() {270; CHECK-NEXT: [[ENTRY:.*:]]271; CHECK-NEXT: [[FOLDS:%.*]] = add nuw nsw <4 x i64> zeroinitializer, zeroinitializer272; CHECK-NEXT: ret <4 x i64> zeroinitializer273;274entry:275 %folds = add <4 x i64> zeroinitializer, zeroinitializer276 ret <4 x i64> %folds277}278 279define <2 x i16> @phi_merge1(i1 %c, <2 x i8> %a) {280; CHECK-LABEL: define range(i16 2, 259) <2 x i16> @phi_merge1(281; CHECK-SAME: i1 [[C:%.*]], <2 x i8> [[A:%.*]]) {282; CHECK-NEXT: [[ENTRY:.*]]:283; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>284; CHECK-NEXT: br i1 [[C]], label %[[IF:.*]], label %[[JOIN:.*]]285; CHECK: [[IF]]:286; CHECK-NEXT: br label %[[JOIN]]287; CHECK: [[JOIN]]:288; CHECK-NEXT: [[PHI:%.*]] = phi <2 x i16> [ [[ZEXT]], %[[ENTRY]] ], [ <i16 1, i16 2>, %[[IF]] ]289; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw <2 x i16> [[PHI]], <i16 2, i16 3>290; CHECK-NEXT: ret <2 x i16> [[ADD]]291;292entry:293 %zext = zext <2 x i8> %a to <2 x i16>294 br i1 %c, label %if, label %join295 296if:297 br label %join298 299join:300 %phi = phi <2 x i16> [ %zext, %entry ], [ <i16 1, i16 2>, %if ]301 %add = add <2 x i16> %phi, <i16 2, i16 3>302 ret <2 x i16> %add303}304 305define <2 x i16> @phi_merge2(i1 %c, <2 x i8> %a) {306; CHECK-LABEL: define range(i16 2, 259) <2 x i16> @phi_merge2(307; CHECK-SAME: i1 [[C:%.*]], <2 x i8> [[A:%.*]]) {308; CHECK-NEXT: [[ENTRY:.*]]:309; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>310; CHECK-NEXT: br i1 [[C]], label %[[IF:.*]], label %[[JOIN:.*]]311; CHECK: [[IF]]:312; CHECK-NEXT: br label %[[JOIN]]313; CHECK: [[JOIN]]:314; CHECK-NEXT: [[PHI:%.*]] = phi <2 x i16> [ <i16 1, i16 2>, %[[ENTRY]] ], [ [[ZEXT]], %[[IF]] ]315; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw <2 x i16> [[PHI]], <i16 2, i16 3>316; CHECK-NEXT: ret <2 x i16> [[ADD]]317;318entry:319 %zext = zext <2 x i8> %a to <2 x i16>320 br i1 %c, label %if, label %join321 322if:323 br label %join324 325join:326 %phi = phi <2 x i16> [ <i16 1, i16 2>, %entry ], [ %zext, %if ]327 %add = add <2 x i16> %phi, <i16 2, i16 3>328 ret <2 x i16> %add329}330 331;; Check if ICMP instruction is constant folded or not.332define <2 x i1> @insertelement_fold1() {333; CHECK-LABEL: define <2 x i1> @insertelement_fold1() {334; CHECK-NEXT: [[IE1:%.*]] = insertelement <2 x i32> poison, i32 10, i64 0335; CHECK-NEXT: [[IE2:%.*]] = insertelement <2 x i32> [[IE1]], i32 20, i64 1336; CHECK-NEXT: ret <2 x i1> splat (i1 true)337;338 %ie1 = insertelement <2 x i32> poison, i32 10, i64 0339 %ie2 = insertelement <2 x i32> %ie1, i32 20, i64 1340 %icmp1 = icmp slt <2 x i32> %ie2, <i32 1024, i32 1024>341 ret <2 x i1> %icmp1342}343 344;; Check if LVI is able to handle constant vector operands345;; in InsertElementInst and CVP is able to fold ICMP instruction.346define <2 x i1> @insertelement_fold2() {347; CHECK-LABEL: define <2 x i1> @insertelement_fold2() {348; CHECK-NEXT: [[IE1:%.*]] = insertelement <2 x i32> <i32 poison, i32 20>, i32 10, i64 0349; CHECK-NEXT: ret <2 x i1> splat (i1 true)350;351 %ie1 = insertelement <2 x i32> <i32 poison, i32 20>, i32 10, i64 0352 %icmp1 = icmp slt <2 x i32> %ie1, <i32 1024, i32 1024>353 ret <2 x i1> %icmp1354}355 356@g = external global i32357 358define <2 x i16> @insertelement_constexpr() {359; CHECK-LABEL: define <2 x i16> @insertelement_constexpr() {360; CHECK-NEXT: [[INS:%.*]] = insertelement <2 x i16> poison, i16 ptrtoint (ptr @g to i16), i32 0361; CHECK-NEXT: ret <2 x i16> [[INS]]362;363 %ins = insertelement <2 x i16> poison, i16 ptrtoint (ptr @g to i16), i32 0364 ret <2 x i16> %ins365}366