405 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; rdar://117480245 6define i32 @a(i1 zeroext %x, i1 zeroext %y) {7; CHECK-LABEL: @a(8; CHECK-NEXT: [[CONV3_NEG1:%.*]] = sext i1 [[Y:%.*]] to i329; CHECK-NEXT: [[SUB:%.*]] = select i1 [[X:%.*]], i32 2, i32 110; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[SUB]], [[CONV3_NEG1]]11; CHECK-NEXT: ret i32 [[ADD]]12;13 %conv = zext i1 %x to i3214 %conv3 = zext i1 %y to i3215 %conv3.neg = sub i32 0, %conv316 %sub = add i32 %conv, 117 %add = add i32 %sub, %conv3.neg18 ret i32 %add19}20 21define i32 @PR30273_select(i1 %a, i1 %b) {22; CHECK-LABEL: @PR30273_select(23; CHECK-NEXT: [[ZEXT:%.*]] = zext i1 [[A:%.*]] to i3224; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[A]], i32 2, i32 125; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[B:%.*]], i32 [[SEL1]], i32 [[ZEXT]]26; CHECK-NEXT: ret i32 [[SEL2]]27;28 %zext = zext i1 %a to i3229 %sel1 = select i1 %a, i32 2, i32 130 %sel2 = select i1 %b, i32 %sel1, i32 %zext31 ret i32 %sel232}33 34define i32 @PR30273_zext_add(i1 %a, i1 %b) {35; CHECK-LABEL: @PR30273_zext_add(36; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[A:%.*]] to i3237; CHECK-NEXT: [[CONV3:%.*]] = zext i1 [[B:%.*]] to i3238; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[CONV3]], [[CONV]]39; CHECK-NEXT: ret i32 [[ADD]]40;41 %conv = zext i1 %a to i3242 %conv3 = zext i1 %b to i3243 %add = add nuw nsw i32 %conv3, %conv44 ret i32 %add45}46 47define i32 @PR30273_three_bools(i1 %x, i1 %y, i1 %z) {48; CHECK-LABEL: @PR30273_three_bools(49; CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[X:%.*]] to i3250; CHECK-NEXT: [[ADD1:%.*]] = select i1 [[X]], i32 2, i32 151; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[Y:%.*]], i32 [[ADD1]], i32 [[FROMBOOL]]52; CHECK-NEXT: [[ADD2:%.*]] = zext i1 [[Z:%.*]] to i3253; CHECK-NEXT: [[SEL2:%.*]] = add nuw nsw i32 [[SEL1]], [[ADD2]]54; CHECK-NEXT: ret i32 [[SEL2]]55;56 %frombool = zext i1 %x to i3257 %add1 = add nsw i32 %frombool, 158 %sel1 = select i1 %y, i32 %add1, i32 %frombool59 %add2 = add nsw i32 %sel1, 160 %sel2 = select i1 %z, i32 %add2, i32 %sel161 ret i32 %sel262}63 64define i32 @zext_add_scalar(i1 %x) {65; CHECK-LABEL: @zext_add_scalar(66; CHECK-NEXT: [[ADD:%.*]] = select i1 [[X:%.*]], i32 43, i32 4267; CHECK-NEXT: ret i32 [[ADD]]68;69 %zext = zext i1 %x to i3270 %add = add i32 %zext, 4271 ret i32 %add72}73 74define <2 x i32> @zext_add_vec_splat(<2 x i1> %x) {75; CHECK-LABEL: @zext_add_vec_splat(76; CHECK-NEXT: [[ADD:%.*]] = select <2 x i1> [[X:%.*]], <2 x i32> splat (i32 43), <2 x i32> splat (i32 42)77; CHECK-NEXT: ret <2 x i32> [[ADD]]78;79 %zext = zext <2 x i1> %x to <2 x i32>80 %add = add <2 x i32> %zext, <i32 42, i32 42>81 ret <2 x i32> %add82}83 84define <2 x i32> @zext_add_vec(<2 x i1> %x) {85; CHECK-LABEL: @zext_add_vec(86; CHECK-NEXT: [[ADD:%.*]] = select <2 x i1> [[X:%.*]], <2 x i32> <i32 43, i32 24>, <2 x i32> <i32 42, i32 23>87; CHECK-NEXT: ret <2 x i32> [[ADD]]88;89 %zext = zext <2 x i1> %x to <2 x i32>90 %add = add <2 x i32> %zext, <i32 42, i32 23>91 ret <2 x i32> %add92}93 94declare void @use(i64)95 96define i64 @zext_negate(i1 %A) {97; CHECK-LABEL: @zext_negate(98; CHECK-NEXT: [[EXT_NEG:%.*]] = sext i1 [[A:%.*]] to i6499; CHECK-NEXT: ret i64 [[EXT_NEG]]100;101 %ext = zext i1 %A to i64102 %sub = sub i64 0, %ext103 ret i64 %sub104}105 106define i64 @zext_negate_extra_use(i1 %A) {107; CHECK-LABEL: @zext_negate_extra_use(108; CHECK-NEXT: [[EXT_NEG:%.*]] = sext i1 [[A:%.*]] to i64109; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[A]] to i64110; CHECK-NEXT: call void @use(i64 [[EXT]])111; CHECK-NEXT: ret i64 [[EXT_NEG]]112;113 %ext = zext i1 %A to i64114 %sub = sub i64 0, %ext115 call void @use(i64 %ext)116 ret i64 %sub117}118 119define <2 x i64> @zext_negate_vec(<2 x i1> %A) {120; CHECK-LABEL: @zext_negate_vec(121; CHECK-NEXT: [[EXT_NEG:%.*]] = sext <2 x i1> [[A:%.*]] to <2 x i64>122; CHECK-NEXT: ret <2 x i64> [[EXT_NEG]]123;124 %ext = zext <2 x i1> %A to <2 x i64>125 %sub = sub <2 x i64> zeroinitializer, %ext126 ret <2 x i64> %sub127}128 129define <2 x i64> @zext_negate_vec_poison_elt(<2 x i1> %A) {130; CHECK-LABEL: @zext_negate_vec_poison_elt(131; CHECK-NEXT: [[EXT_NEG:%.*]] = sext <2 x i1> [[A:%.*]] to <2 x i64>132; CHECK-NEXT: ret <2 x i64> [[EXT_NEG]]133;134 %ext = zext <2 x i1> %A to <2 x i64>135 %sub = sub <2 x i64> <i64 0, i64 poison>, %ext136 ret <2 x i64> %sub137}138 139define i64 @zext_sub_const(i1 %A) {140; CHECK-LABEL: @zext_sub_const(141; CHECK-NEXT: [[SUB:%.*]] = select i1 [[A:%.*]], i64 41, i64 42142; CHECK-NEXT: ret i64 [[SUB]]143;144 %ext = zext i1 %A to i64145 %sub = sub i64 42, %ext146 ret i64 %sub147}148 149define i64 @zext_sub_const_extra_use(i1 %A) {150; CHECK-LABEL: @zext_sub_const_extra_use(151; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[A:%.*]] to i64152; CHECK-NEXT: [[SUB:%.*]] = select i1 [[A]], i64 41, i64 42153; CHECK-NEXT: call void @use(i64 [[EXT]])154; CHECK-NEXT: ret i64 [[SUB]]155;156 %ext = zext i1 %A to i64157 %sub = sub i64 42, %ext158 call void @use(i64 %ext)159 ret i64 %sub160}161 162define <2 x i64> @zext_sub_const_vec(<2 x i1> %A) {163; CHECK-LABEL: @zext_sub_const_vec(164; CHECK-NEXT: [[SUB:%.*]] = select <2 x i1> [[A:%.*]], <2 x i64> <i64 41, i64 2>, <2 x i64> <i64 42, i64 3>165; CHECK-NEXT: ret <2 x i64> [[SUB]]166;167 %ext = zext <2 x i1> %A to <2 x i64>168 %sub = sub <2 x i64> <i64 42, i64 3>, %ext169 ret <2 x i64> %sub170}171 172define <2 x i64> @zext_sub_const_vec_poison_elt(<2 x i1> %A) {173; CHECK-LABEL: @zext_sub_const_vec_poison_elt(174; CHECK-NEXT: [[SUB:%.*]] = select <2 x i1> [[A:%.*]], <2 x i64> <i64 41, i64 poison>, <2 x i64> <i64 42, i64 poison>175; CHECK-NEXT: ret <2 x i64> [[SUB]]176;177 %ext = zext <2 x i1> %A to <2 x i64>178 %sub = sub <2 x i64> <i64 42, i64 poison>, %ext179 ret <2 x i64> %sub180}181 182define i64 @sext_negate(i1 %A) {183; CHECK-LABEL: @sext_negate(184; CHECK-NEXT: [[EXT_NEG:%.*]] = zext i1 [[A:%.*]] to i64185; CHECK-NEXT: ret i64 [[EXT_NEG]]186;187 %ext = sext i1 %A to i64188 %sub = sub i64 0, %ext189 ret i64 %sub190}191 192define i64 @sext_negate_extra_use(i1 %A) {193; CHECK-LABEL: @sext_negate_extra_use(194; CHECK-NEXT: [[EXT_NEG:%.*]] = zext i1 [[A:%.*]] to i64195; CHECK-NEXT: [[EXT:%.*]] = sext i1 [[A]] to i64196; CHECK-NEXT: call void @use(i64 [[EXT]])197; CHECK-NEXT: ret i64 [[EXT_NEG]]198;199 %ext = sext i1 %A to i64200 %sub = sub i64 0, %ext201 call void @use(i64 %ext)202 ret i64 %sub203}204 205define <2 x i64> @sext_negate_vec(<2 x i1> %A) {206; CHECK-LABEL: @sext_negate_vec(207; CHECK-NEXT: [[EXT_NEG:%.*]] = zext <2 x i1> [[A:%.*]] to <2 x i64>208; CHECK-NEXT: ret <2 x i64> [[EXT_NEG]]209;210 %ext = sext <2 x i1> %A to <2 x i64>211 %sub = sub <2 x i64> zeroinitializer, %ext212 ret <2 x i64> %sub213}214 215define <2 x i64> @sext_negate_vec_poison_elt(<2 x i1> %A) {216; CHECK-LABEL: @sext_negate_vec_poison_elt(217; CHECK-NEXT: [[EXT_NEG:%.*]] = zext <2 x i1> [[A:%.*]] to <2 x i64>218; CHECK-NEXT: ret <2 x i64> [[EXT_NEG]]219;220 %ext = sext <2 x i1> %A to <2 x i64>221 %sub = sub <2 x i64> <i64 0, i64 poison>, %ext222 ret <2 x i64> %sub223}224 225define i64 @sext_sub_const(i1 %A) {226; CHECK-LABEL: @sext_sub_const(227; CHECK-NEXT: [[SUB:%.*]] = select i1 [[A:%.*]], i64 43, i64 42228; CHECK-NEXT: ret i64 [[SUB]]229;230 %ext = sext i1 %A to i64231 %sub = sub i64 42, %ext232 ret i64 %sub233}234 235define i64 @sext_sub_const_extra_use(i1 %A) {236; CHECK-LABEL: @sext_sub_const_extra_use(237; CHECK-NEXT: [[EXT:%.*]] = sext i1 [[A:%.*]] to i64238; CHECK-NEXT: [[SUB:%.*]] = select i1 [[A]], i64 43, i64 42239; CHECK-NEXT: call void @use(i64 [[EXT]])240; CHECK-NEXT: ret i64 [[SUB]]241;242 %ext = sext i1 %A to i64243 %sub = sub i64 42, %ext244 call void @use(i64 %ext)245 ret i64 %sub246}247 248define <2 x i64> @sext_sub_const_vec(<2 x i1> %A) {249; CHECK-LABEL: @sext_sub_const_vec(250; CHECK-NEXT: [[SUB:%.*]] = select <2 x i1> [[A:%.*]], <2 x i64> <i64 43, i64 4>, <2 x i64> <i64 42, i64 3>251; CHECK-NEXT: ret <2 x i64> [[SUB]]252;253 %ext = sext <2 x i1> %A to <2 x i64>254 %sub = sub <2 x i64> <i64 42, i64 3>, %ext255 ret <2 x i64> %sub256}257 258define <2 x i64> @sext_sub_const_vec_poison_elt(<2 x i1> %A) {259; CHECK-LABEL: @sext_sub_const_vec_poison_elt(260; CHECK-NEXT: [[SUB:%.*]] = select <2 x i1> [[A:%.*]], <2 x i64> <i64 poison, i64 43>, <2 x i64> <i64 poison, i64 42>261; CHECK-NEXT: ret <2 x i64> [[SUB]]262;263 %ext = sext <2 x i1> %A to <2 x i64>264 %sub = sub <2 x i64> <i64 poison, i64 42>, %ext265 ret <2 x i64> %sub266}267 268define i8 @sext_sub(i8 %x, i1 %y) {269; CHECK-LABEL: @sext_sub(270; CHECK-NEXT: [[SEXT_NEG:%.*]] = zext i1 [[Y:%.*]] to i8271; CHECK-NEXT: [[SUB:%.*]] = add i8 [[X:%.*]], [[SEXT_NEG]]272; CHECK-NEXT: ret i8 [[SUB]]273;274 %sext = sext i1 %y to i8275 %sub = sub i8 %x, %sext276 ret i8 %sub277}278 279; Vectors get the same transform.280 281define <2 x i8> @sext_sub_vec(<2 x i8> %x, <2 x i1> %y) {282; CHECK-LABEL: @sext_sub_vec(283; CHECK-NEXT: [[SEXT_NEG:%.*]] = zext <2 x i1> [[Y:%.*]] to <2 x i8>284; CHECK-NEXT: [[SUB:%.*]] = add <2 x i8> [[X:%.*]], [[SEXT_NEG]]285; CHECK-NEXT: ret <2 x i8> [[SUB]]286;287 %sext = sext <2 x i1> %y to <2 x i8>288 %sub = sub <2 x i8> %x, %sext289 ret <2 x i8> %sub290}291 292; NSW is preserved.293 294define <2 x i8> @sext_sub_vec_nsw(<2 x i8> %x, <2 x i1> %y) {295; CHECK-LABEL: @sext_sub_vec_nsw(296; CHECK-NEXT: [[SEXT_NEG:%.*]] = zext <2 x i1> [[Y:%.*]] to <2 x i8>297; CHECK-NEXT: [[SUB:%.*]] = add <2 x i8> [[X:%.*]], [[SEXT_NEG]]298; CHECK-NEXT: ret <2 x i8> [[SUB]]299;300 %sext = sext <2 x i1> %y to <2 x i8>301 %sub = sub nsw <2 x i8> %x, %sext302 ret <2 x i8> %sub303}304 305; We favor the canonical zext+add over keeping the NUW.306 307define i8 @sext_sub_nuw(i8 %x, i1 %y) {308; CHECK-LABEL: @sext_sub_nuw(309; CHECK-NEXT: [[SEXT_NEG:%.*]] = zext i1 [[Y:%.*]] to i8310; CHECK-NEXT: [[SUB:%.*]] = add i8 [[X:%.*]], [[SEXT_NEG]]311; CHECK-NEXT: ret i8 [[SUB]]312;313 %sext = sext i1 %y to i8314 %sub = sub nuw i8 %x, %sext315 ret i8 %sub316}317 318define i32 @sextbool_add(i1 %c, i32 %x) {319; CHECK-LABEL: @sextbool_add(320; CHECK-NEXT: [[B:%.*]] = sext i1 [[C:%.*]] to i32321; CHECK-NEXT: [[S:%.*]] = add i32 [[X:%.*]], [[B]]322; CHECK-NEXT: ret i32 [[S]]323;324 %b = sext i1 %c to i32325 %s = add i32 %b, %x326 ret i32 %s327}328 329define i32 @sextbool_add_commute(i1 %c, i32 %px) {330; CHECK-LABEL: @sextbool_add_commute(331; CHECK-NEXT: [[X:%.*]] = urem i32 [[PX:%.*]], 42332; CHECK-NEXT: [[B:%.*]] = sext i1 [[C:%.*]] to i32333; CHECK-NEXT: [[S:%.*]] = add nsw i32 [[X]], [[B]]334; CHECK-NEXT: ret i32 [[S]]335;336 %x = urem i32 %px, 42 ; thwart complexity-based canonicalization337 %b = sext i1 %c to i32338 %s = add i32 %x, %b339 ret i32 %s340}341 342; Negative test - extra use prevents canonicalization.343 344declare void @use32(i32)345 346define i32 @sextbool_add_uses(i1 %c, i32 %x) {347; CHECK-LABEL: @sextbool_add_uses(348; CHECK-NEXT: [[B:%.*]] = sext i1 [[C:%.*]] to i32349; CHECK-NEXT: call void @use32(i32 [[B]])350; CHECK-NEXT: [[S:%.*]] = add i32 [[X:%.*]], [[B]]351; CHECK-NEXT: ret i32 [[S]]352;353 %b = sext i1 %c to i32354 call void @use32(i32 %b)355 %s = add i32 %b, %x356 ret i32 %s357}358 359define <4 x i32> @sextbool_add_vector(<4 x i1> %c, <4 x i32> %x) {360; CHECK-LABEL: @sextbool_add_vector(361; CHECK-NEXT: [[B:%.*]] = sext <4 x i1> [[C:%.*]] to <4 x i32>362; CHECK-NEXT: [[S:%.*]] = add <4 x i32> [[X:%.*]], [[B]]363; CHECK-NEXT: ret <4 x i32> [[S]]364;365 %b = sext <4 x i1> %c to <4 x i32>366 %s = add <4 x i32> %x, %b367 ret <4 x i32> %s368}369 370define i32 @zextbool_sub(i1 %c, i32 %x) {371; CHECK-LABEL: @zextbool_sub(372; CHECK-NEXT: [[B:%.*]] = zext i1 [[C:%.*]] to i32373; CHECK-NEXT: [[S:%.*]] = sub i32 [[B]], [[X:%.*]]374; CHECK-NEXT: ret i32 [[S]]375;376 %b = zext i1 %c to i32377 %s = sub i32 %b, %x378 ret i32 %s379}380 381define i32 @zextbool_sub_uses(i1 %c, i32 %x) {382; CHECK-LABEL: @zextbool_sub_uses(383; CHECK-NEXT: [[B:%.*]] = zext i1 [[C:%.*]] to i32384; CHECK-NEXT: call void @use32(i32 [[B]])385; CHECK-NEXT: [[S:%.*]] = sub i32 [[X:%.*]], [[B]]386; CHECK-NEXT: ret i32 [[S]]387;388 %b = zext i1 %c to i32389 call void @use32(i32 %b)390 %s = sub i32 %x, %b391 ret i32 %s392}393 394define <4 x i32> @zextbool_sub_vector(<4 x i1> %c, <4 x i32> %x) {395; CHECK-LABEL: @zextbool_sub_vector(396; CHECK-NEXT: [[B_NEG:%.*]] = sext <4 x i1> [[C:%.*]] to <4 x i32>397; CHECK-NEXT: [[S:%.*]] = add <4 x i32> [[X:%.*]], [[B_NEG]]398; CHECK-NEXT: ret <4 x i32> [[S]]399;400 %b = zext <4 x i1> %c to <4 x i32>401 %s = sub <4 x i32> %x, %b402 ret <4 x i32> %s403}404 405