1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4; rdar://11748024 5 6define i32 @a(i1 zeroext %x, i1 zeroext %y) { 7; CHECK-LABEL: @a( 8; CHECK-NEXT: [[CONV3_NEG1:%.*]] = sext i1 [[Y:%.*]] to i32 9; CHECK-NEXT: [[SUB:%.*]] = select i1 [[X:%.*]], i32 2, i32 1 10; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[SUB]], [[CONV3_NEG1]] 11; CHECK-NEXT: ret i32 [[ADD]] 12; 13 %conv = zext i1 %x to i32 14 %conv3 = zext i1 %y to i32 15 %conv3.neg = sub i32 0, %conv3 16 %sub = add i32 %conv, 1 17 %add = add i32 %sub, %conv3.neg 18 ret i32 %add 19} 20 21define i32 @PR30273_select(i1 %a, i1 %b) { 22; CHECK-LABEL: @PR30273_select( 23; CHECK-NEXT: [[ZEXT:%.*]] = zext i1 [[A:%.*]] to i32 24; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[A]], i32 2, i32 1 25; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[B:%.*]], i32 [[SEL1]], i32 [[ZEXT]] 26; CHECK-NEXT: ret i32 [[SEL2]] 27; 28 %zext = zext i1 %a to i32 29 %sel1 = select i1 %a, i32 2, i32 1 30 %sel2 = select i1 %b, i32 %sel1, i32 %zext 31 ret i32 %sel2 32} 33 34define i32 @PR30273_zext_add(i1 %a, i1 %b) { 35; CHECK-LABEL: @PR30273_zext_add( 36; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[A:%.*]] to i32 37; CHECK-NEXT: [[CONV3:%.*]] = zext i1 [[B:%.*]] to i32 38; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[CONV3]], [[CONV]] 39; CHECK-NEXT: ret i32 [[ADD]] 40; 41 %conv = zext i1 %a to i32 42 %conv3 = zext i1 %b to i32 43 %add = add nuw nsw i32 %conv3, %conv 44 ret i32 %add 45} 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 i32 50; CHECK-NEXT: [[ADD1:%.*]] = select i1 [[X]], i32 2, i32 1 51; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[Y:%.*]], i32 [[ADD1]], i32 [[FROMBOOL]] 52; CHECK-NEXT: [[ADD2:%.*]] = zext i1 [[Z:%.*]] to i32 53; CHECK-NEXT: [[SEL2:%.*]] = add nuw nsw i32 [[SEL1]], [[ADD2]] 54; CHECK-NEXT: ret i32 [[SEL2]] 55; 56 %frombool = zext i1 %x to i32 57 %add1 = add nsw i32 %frombool, 1 58 %sel1 = select i1 %y, i32 %add1, i32 %frombool 59 %add2 = add nsw i32 %sel1, 1 60 %sel2 = select i1 %z, i32 %add2, i32 %sel1 61 ret i32 %sel2 62} 63 64define i32 @zext_add_scalar(i1 %x) { 65; CHECK-LABEL: @zext_add_scalar( 66; CHECK-NEXT: [[ADD:%.*]] = select i1 [[X:%.*]], i32 43, i32 42 67; CHECK-NEXT: ret i32 [[ADD]] 68; 69 %zext = zext i1 %x to i32 70 %add = add i32 %zext, 42 71 ret i32 %add 72} 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> <i32 43, i32 43>, <2 x i32> <i32 42, 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> %add 82} 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> %add 92} 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 i64 99; CHECK-NEXT: ret i64 [[EXT_NEG]] 100; 101 %ext = zext i1 %A to i64 102 %sub = sub i64 0, %ext 103 ret i64 %sub 104} 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 i64 109; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[A]] to i64 110; CHECK-NEXT: call void @use(i64 [[EXT]]) 111; CHECK-NEXT: ret i64 [[EXT_NEG]] 112; 113 %ext = zext i1 %A to i64 114 %sub = sub i64 0, %ext 115 call void @use(i64 %ext) 116 ret i64 %sub 117} 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, %ext 126 ret <2 x i64> %sub 127} 128 129define <2 x i64> @zext_negate_vec_undef_elt(<2 x i1> %A) { 130; CHECK-LABEL: @zext_negate_vec_undef_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 undef>, %ext 136 ret <2 x i64> %sub 137} 138 139define i64 @zext_sub_const(i1 %A) { 140; CHECK-LABEL: @zext_sub_const( 141; CHECK-NEXT: [[SUB:%.*]] = select i1 [[A:%.*]], i64 41, i64 42 142; CHECK-NEXT: ret i64 [[SUB]] 143; 144 %ext = zext i1 %A to i64 145 %sub = sub i64 42, %ext 146 ret i64 %sub 147} 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 i64 152; CHECK-NEXT: [[SUB:%.*]] = select i1 [[A]], i64 41, i64 42 153; CHECK-NEXT: call void @use(i64 [[EXT]]) 154; CHECK-NEXT: ret i64 [[SUB]] 155; 156 %ext = zext i1 %A to i64 157 %sub = sub i64 42, %ext 158 call void @use(i64 %ext) 159 ret i64 %sub 160} 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>, %ext 169 ret <2 x i64> %sub 170} 171 172define <2 x i64> @zext_sub_const_vec_undef_elt(<2 x i1> %A) { 173; CHECK-LABEL: @zext_sub_const_vec_undef_elt( 174; CHECK-NEXT: [[SUB:%.*]] = select <2 x i1> [[A:%.*]], <2 x i64> <i64 41, i64 undef>, <2 x i64> <i64 42, i64 undef> 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 undef>, %ext 179 ret <2 x i64> %sub 180} 181 182define i64 @sext_negate(i1 %A) { 183; CHECK-LABEL: @sext_negate( 184; CHECK-NEXT: [[EXT_NEG:%.*]] = zext i1 [[A:%.*]] to i64 185; CHECK-NEXT: ret i64 [[EXT_NEG]] 186; 187 %ext = sext i1 %A to i64 188 %sub = sub i64 0, %ext 189 ret i64 %sub 190} 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 i64 195; CHECK-NEXT: [[EXT:%.*]] = sext i1 [[A]] to i64 196; CHECK-NEXT: call void @use(i64 [[EXT]]) 197; CHECK-NEXT: ret i64 [[EXT_NEG]] 198; 199 %ext = sext i1 %A to i64 200 %sub = sub i64 0, %ext 201 call void @use(i64 %ext) 202 ret i64 %sub 203} 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, %ext 212 ret <2 x i64> %sub 213} 214 215define <2 x i64> @sext_negate_vec_undef_elt(<2 x i1> %A) { 216; CHECK-LABEL: @sext_negate_vec_undef_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 undef>, %ext 222 ret <2 x i64> %sub 223} 224 225define i64 @sext_sub_const(i1 %A) { 226; CHECK-LABEL: @sext_sub_const( 227; CHECK-NEXT: [[SUB:%.*]] = select i1 [[A:%.*]], i64 43, i64 42 228; CHECK-NEXT: ret i64 [[SUB]] 229; 230 %ext = sext i1 %A to i64 231 %sub = sub i64 42, %ext 232 ret i64 %sub 233} 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 i64 238; CHECK-NEXT: [[SUB:%.*]] = select i1 [[A]], i64 43, i64 42 239; CHECK-NEXT: call void @use(i64 [[EXT]]) 240; CHECK-NEXT: ret i64 [[SUB]] 241; 242 %ext = sext i1 %A to i64 243 %sub = sub i64 42, %ext 244 call void @use(i64 %ext) 245 ret i64 %sub 246} 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>, %ext 255 ret <2 x i64> %sub 256} 257 258define <2 x i64> @sext_sub_const_vec_undef_elt(<2 x i1> %A) { 259; CHECK-LABEL: @sext_sub_const_vec_undef_elt( 260; CHECK-NEXT: [[SUB:%.*]] = select <2 x i1> [[A:%.*]], <2 x i64> <i64 undef, i64 43>, <2 x i64> <i64 undef, 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 undef, i64 42>, %ext 265 ret <2 x i64> %sub 266} 267 268define i8 @sext_sub(i8 %x, i1 %y) { 269; CHECK-LABEL: @sext_sub( 270; CHECK-NEXT: [[SEXT_NEG:%.*]] = zext i1 [[Y:%.*]] to i8 271; CHECK-NEXT: [[SUB:%.*]] = add i8 [[SEXT_NEG]], [[X:%.*]] 272; CHECK-NEXT: ret i8 [[SUB]] 273; 274 %sext = sext i1 %y to i8 275 %sub = sub i8 %x, %sext 276 ret i8 %sub 277} 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> [[SEXT_NEG]], [[X:%.*]] 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, %sext 289 ret <2 x i8> %sub 290} 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> [[SEXT_NEG]], [[X:%.*]] 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, %sext 302 ret <2 x i8> %sub 303} 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 i8 310; CHECK-NEXT: [[SUB:%.*]] = add i8 [[SEXT_NEG]], [[X:%.*]] 311; CHECK-NEXT: ret i8 [[SUB]] 312; 313 %sext = sext i1 %y to i8 314 %sub = sub nuw i8 %x, %sext 315 ret i8 %sub 316} 317 318define i32 @sextbool_add(i1 %c, i32 %x) { 319; CHECK-LABEL: @sextbool_add( 320; CHECK-NEXT: [[B:%.*]] = sext i1 [[C:%.*]] to i32 321; CHECK-NEXT: [[S:%.*]] = add i32 [[B]], [[X:%.*]] 322; CHECK-NEXT: ret i32 [[S]] 323; 324 %b = sext i1 %c to i32 325 %s = add i32 %b, %x 326 ret i32 %s 327} 328 329define i32 @sextbool_add_commute(i1 %c, i32 %px) { 330; CHECK-LABEL: @sextbool_add_commute( 331; CHECK-NEXT: [[X:%.*]] = urem i32 [[PX:%.*]], 42 332; CHECK-NEXT: [[B:%.*]] = sext i1 [[C:%.*]] to i32 333; CHECK-NEXT: [[S:%.*]] = add nsw i32 [[X]], [[B]] 334; CHECK-NEXT: ret i32 [[S]] 335; 336 %x = urem i32 %px, 42 ; thwart complexity-based canonicalization 337 %b = sext i1 %c to i32 338 %s = add i32 %x, %b 339 ret i32 %s 340} 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 i32 349; CHECK-NEXT: call void @use32(i32 [[B]]) 350; CHECK-NEXT: [[S:%.*]] = add i32 [[B]], [[X:%.*]] 351; CHECK-NEXT: ret i32 [[S]] 352; 353 %b = sext i1 %c to i32 354 call void @use32(i32 %b) 355 %s = add i32 %b, %x 356 ret i32 %s 357} 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> [[B]], [[X:%.*]] 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, %b 367 ret <4 x i32> %s 368} 369 370define i32 @zextbool_sub(i1 %c, i32 %x) { 371; CHECK-LABEL: @zextbool_sub( 372; CHECK-NEXT: [[B:%.*]] = zext i1 [[C:%.*]] to i32 373; CHECK-NEXT: [[S:%.*]] = sub i32 [[B]], [[X:%.*]] 374; CHECK-NEXT: ret i32 [[S]] 375; 376 %b = zext i1 %c to i32 377 %s = sub i32 %b, %x 378 ret i32 %s 379} 380 381define i32 @zextbool_sub_uses(i1 %c, i32 %x) { 382; CHECK-LABEL: @zextbool_sub_uses( 383; CHECK-NEXT: [[B:%.*]] = zext i1 [[C:%.*]] to i32 384; 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 i32 389 call void @use32(i32 %b) 390 %s = sub i32 %x, %b 391 ret i32 %s 392} 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> [[B_NEG]], [[X:%.*]] 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, %b 402 ret <4 x i32> %s 403} 404 405