22; RUN: opt < %s -passes=instcombine -S | FileCheck %s
33
44declare void @use (i32 )
5+ declare void @use_i16 (i8 )
6+ declare void @use_2xi16 (<2 x i16 >)
57declare void @use_i8 (i8 )
68declare void @use_i1 (i1 )
79
@@ -4250,8 +4252,8 @@ define i16 @and_zext_zext(i8 %x, i4 %y) {
42504252; CHECK-LABEL: define {{[^@]+}}@and_zext_zext
42514253; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
42524254; CHECK-NEXT: [[TMP1:%.*]] = zext i4 [[Y]] to i8
4253- ; CHECK-NEXT: [[TMP2 :%.*]] = and i8 [[X]], [[TMP1]]
4254- ; CHECK-NEXT: [[R:%.*]] = zext nneg i8 [[TMP2 ]] to i16
4255+ ; CHECK-NEXT: [[R1 :%.*]] = and i8 [[X]], [[TMP1]]
4256+ ; CHECK-NEXT: [[R:%.*]] = zext nneg i8 [[R1 ]] to i16
42554257; CHECK-NEXT: ret i16 [[R]]
42564258;
42574259 %zx = zext i8 %x to i16
@@ -4260,12 +4262,41 @@ define i16 @and_zext_zext(i8 %x, i4 %y) {
42604262 ret i16 %r
42614263}
42624264
4265+ define i16 @and_zext_zext_2 (i8 %x , i8 %y ) {
4266+ ; CHECK-LABEL: define {{[^@]+}}@and_zext_zext_2
4267+ ; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
4268+ ; CHECK-NEXT: [[R1:%.*]] = and i8 [[X]], [[Y]]
4269+ ; CHECK-NEXT: [[R:%.*]] = zext i8 [[R1]] to i16
4270+ ; CHECK-NEXT: ret i16 [[R]]
4271+ ;
4272+ %zx = zext i8 %x to i16
4273+ %zy = zext i8 %y to i16
4274+ %r = and i16 %zx , %zy
4275+ ret i16 %r
4276+ }
4277+
4278+ define i16 @and_zext_zext_2_use1 (i8 %x , i8 %y ) {
4279+ ; CHECK-LABEL: define {{[^@]+}}@and_zext_zext_2_use1
4280+ ; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
4281+ ; CHECK-NEXT: [[ZX:%.*]] = zext i8 [[X]] to i16
4282+ ; CHECK-NEXT: call void @use_i16(i16 [[ZX]])
4283+ ; CHECK-NEXT: [[R1:%.*]] = and i8 [[X]], [[Y]]
4284+ ; CHECK-NEXT: [[R:%.*]] = zext i8 [[R1]] to i16
4285+ ; CHECK-NEXT: ret i16 [[R]]
4286+ ;
4287+ %zx = zext i8 %x to i16
4288+ call void @use_i16 (i16 %zx )
4289+ %zy = zext i8 %y to i16
4290+ %r = and i16 %zx , %zy
4291+ ret i16 %r
4292+ }
4293+
42634294define i16 @or_zext_zext (i8 %x , i4 %y ) {
42644295; CHECK-LABEL: define {{[^@]+}}@or_zext_zext
42654296; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
42664297; CHECK-NEXT: [[TMP1:%.*]] = zext i4 [[Y]] to i8
4267- ; CHECK-NEXT: [[TMP2 :%.*]] = or i8 [[X]], [[TMP1]]
4268- ; CHECK-NEXT: [[R:%.*]] = zext i8 [[TMP2 ]] to i16
4298+ ; CHECK-NEXT: [[R1 :%.*]] = or i8 [[X]], [[TMP1]]
4299+ ; CHECK-NEXT: [[R:%.*]] = zext i8 [[R1 ]] to i16
42694300; CHECK-NEXT: ret i16 [[R]]
42704301;
42714302 %zx = zext i8 %x to i16
@@ -4274,12 +4305,41 @@ define i16 @or_zext_zext(i8 %x, i4 %y) {
42744305 ret i16 %r
42754306}
42764307
4308+ define i16 @or_zext_zext_2 (i8 %x , i8 %y ) {
4309+ ; CHECK-LABEL: define {{[^@]+}}@or_zext_zext_2
4310+ ; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
4311+ ; CHECK-NEXT: [[R1:%.*]] = or i8 [[Y]], [[X]]
4312+ ; CHECK-NEXT: [[R:%.*]] = zext i8 [[R1]] to i16
4313+ ; CHECK-NEXT: ret i16 [[R]]
4314+ ;
4315+ %zx = zext i8 %x to i16
4316+ %zy = zext i8 %y to i16
4317+ %r = or i16 %zy , %zx
4318+ ret i16 %r
4319+ }
4320+
4321+ define i16 @or_zext_zext_2_use1 (i8 %x , i8 %y ) {
4322+ ; CHECK-LABEL: define {{[^@]+}}@or_zext_zext_2_use1
4323+ ; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
4324+ ; CHECK-NEXT: [[ZX:%.*]] = zext i8 [[X]] to i16
4325+ ; CHECK-NEXT: call void @use_i16(i16 [[ZX]])
4326+ ; CHECK-NEXT: [[R1:%.*]] = or i8 [[Y]], [[X]]
4327+ ; CHECK-NEXT: [[R:%.*]] = zext i8 [[R1]] to i16
4328+ ; CHECK-NEXT: ret i16 [[R]]
4329+ ;
4330+ %zx = zext i8 %x to i16
4331+ call void @use_i16 (i16 %zx )
4332+ %zy = zext i8 %y to i16
4333+ %r = or i16 %zy , %zx
4334+ ret i16 %r
4335+ }
4336+
42774337define <2 x i16 > @xor_zext_zext (<2 x i8 > %x , <2 x i4 > %y ) {
42784338; CHECK-LABEL: define {{[^@]+}}@xor_zext_zext
42794339; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i4> [[Y:%.*]]) {
42804340; CHECK-NEXT: [[TMP1:%.*]] = zext <2 x i4> [[Y]] to <2 x i8>
4281- ; CHECK-NEXT: [[TMP2 :%.*]] = xor <2 x i8> [[X]], [[TMP1]]
4282- ; CHECK-NEXT: [[R:%.*]] = zext <2 x i8> [[TMP2 ]] to <2 x i16>
4341+ ; CHECK-NEXT: [[R1 :%.*]] = xor <2 x i8> [[X]], [[TMP1]]
4342+ ; CHECK-NEXT: [[R:%.*]] = zext <2 x i8> [[R1 ]] to <2 x i16>
42834343; CHECK-NEXT: ret <2 x i16> [[R]]
42844344;
42854345 %zx = zext <2 x i8 > %x to <2 x i16 >
@@ -4288,12 +4348,41 @@ define <2 x i16> @xor_zext_zext(<2 x i8> %x, <2 x i4> %y) {
42884348 ret <2 x i16 > %r
42894349}
42904350
4351+ define <2 x i16 > @xor_zext_zext_2 (<2 x i8 > %x , <2 x i8 > %y ) {
4352+ ; CHECK-LABEL: define {{[^@]+}}@xor_zext_zext_2
4353+ ; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {
4354+ ; CHECK-NEXT: [[R1:%.*]] = xor <2 x i8> [[X]], [[Y]]
4355+ ; CHECK-NEXT: [[R:%.*]] = zext <2 x i8> [[R1]] to <2 x i16>
4356+ ; CHECK-NEXT: ret <2 x i16> [[R]]
4357+ ;
4358+ %zx = zext <2 x i8 > %x to <2 x i16 >
4359+ %zy = zext <2 x i8 > %y to <2 x i16 >
4360+ %r = xor <2 x i16 > %zx , %zy
4361+ ret <2 x i16 > %r
4362+ }
4363+
4364+ define <2 x i16 > @xor_zext_zext_2_use1 (<2 x i8 > %x , <2 x i8 > %y ) {
4365+ ; CHECK-LABEL: define {{[^@]+}}@xor_zext_zext_2_use1
4366+ ; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {
4367+ ; CHECK-NEXT: [[ZX:%.*]] = zext <2 x i8> [[X]] to <2 x i16>
4368+ ; CHECK-NEXT: call void @use_2xi16(<2 x i16> [[ZX]])
4369+ ; CHECK-NEXT: [[R1:%.*]] = xor <2 x i8> [[X]], [[Y]]
4370+ ; CHECK-NEXT: [[R:%.*]] = zext <2 x i8> [[R1]] to <2 x i16>
4371+ ; CHECK-NEXT: ret <2 x i16> [[R]]
4372+ ;
4373+ %zx = zext <2 x i8 > %x to <2 x i16 >
4374+ call void @use_2xi16 (<2 x i16 > %zx )
4375+ %zy = zext <2 x i8 > %y to <2 x i16 >
4376+ %r = xor <2 x i16 > %zx , %zy
4377+ ret <2 x i16 > %r
4378+ }
4379+
42914380define i16 @and_sext_sext (i8 %x , i4 %y ) {
42924381; CHECK-LABEL: define {{[^@]+}}@and_sext_sext
42934382; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
42944383; CHECK-NEXT: [[TMP1:%.*]] = sext i4 [[Y]] to i8
4295- ; CHECK-NEXT: [[TMP2 :%.*]] = and i8 [[X]], [[TMP1]]
4296- ; CHECK-NEXT: [[R:%.*]] = sext i8 [[TMP2 ]] to i16
4384+ ; CHECK-NEXT: [[R1 :%.*]] = and i8 [[X]], [[TMP1]]
4385+ ; CHECK-NEXT: [[R:%.*]] = sext i8 [[R1 ]] to i16
42974386; CHECK-NEXT: ret i16 [[R]]
42984387;
42994388 %sx = sext i8 %x to i16
@@ -4302,12 +4391,41 @@ define i16 @and_sext_sext(i8 %x, i4 %y) {
43024391 ret i16 %r
43034392}
43044393
4394+ define i16 @and_sext_sext_2 (i8 %x , i8 %y ) {
4395+ ; CHECK-LABEL: define {{[^@]+}}@and_sext_sext_2
4396+ ; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
4397+ ; CHECK-NEXT: [[R1:%.*]] = and i8 [[Y]], [[X]]
4398+ ; CHECK-NEXT: [[R:%.*]] = sext i8 [[R1]] to i16
4399+ ; CHECK-NEXT: ret i16 [[R]]
4400+ ;
4401+ %sx = sext i8 %x to i16
4402+ %sy = sext i8 %y to i16
4403+ %r = and i16 %sy , %sx
4404+ ret i16 %r
4405+ }
4406+
4407+ define i16 @and_sext_sext_2_use1 (i8 %x , i8 %y ) {
4408+ ; CHECK-LABEL: define {{[^@]+}}@and_sext_sext_2_use1
4409+ ; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
4410+ ; CHECK-NEXT: [[SX:%.*]] = sext i8 [[X]] to i16
4411+ ; CHECK-NEXT: call void @use_i16(i16 [[SX]])
4412+ ; CHECK-NEXT: [[R1:%.*]] = and i8 [[Y]], [[X]]
4413+ ; CHECK-NEXT: [[R:%.*]] = sext i8 [[R1]] to i16
4414+ ; CHECK-NEXT: ret i16 [[R]]
4415+ ;
4416+ %sx = sext i8 %x to i16
4417+ call void @use_i16 (i16 %sx )
4418+ %sy = sext i8 %y to i16
4419+ %r = and i16 %sy , %sx
4420+ ret i16 %r
4421+ }
4422+
43054423define i16 @or_sext_sext (i8 %x , i4 %y ) {
43064424; CHECK-LABEL: define {{[^@]+}}@or_sext_sext
43074425; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
43084426; CHECK-NEXT: [[TMP1:%.*]] = sext i4 [[Y]] to i8
4309- ; CHECK-NEXT: [[TMP2 :%.*]] = or i8 [[X]], [[TMP1]]
4310- ; CHECK-NEXT: [[R:%.*]] = sext i8 [[TMP2 ]] to i16
4427+ ; CHECK-NEXT: [[R1 :%.*]] = or i8 [[X]], [[TMP1]]
4428+ ; CHECK-NEXT: [[R:%.*]] = sext i8 [[R1 ]] to i16
43114429; CHECK-NEXT: ret i16 [[R]]
43124430;
43134431 %sx = sext i8 %x to i16
@@ -4316,12 +4434,41 @@ define i16 @or_sext_sext(i8 %x, i4 %y) {
43164434 ret i16 %r
43174435}
43184436
4437+ define i16 @or_sext_sext_2 (i8 %x , i8 %y ) {
4438+ ; CHECK-LABEL: define {{[^@]+}}@or_sext_sext_2
4439+ ; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
4440+ ; CHECK-NEXT: [[R1:%.*]] = or i8 [[X]], [[Y]]
4441+ ; CHECK-NEXT: [[R:%.*]] = sext i8 [[R1]] to i16
4442+ ; CHECK-NEXT: ret i16 [[R]]
4443+ ;
4444+ %sx = sext i8 %x to i16
4445+ %sy = sext i8 %y to i16
4446+ %r = or i16 %sx , %sy
4447+ ret i16 %r
4448+ }
4449+
4450+ define i16 @or_sext_sext_2_use1 (i8 %x , i8 %y ) {
4451+ ; CHECK-LABEL: define {{[^@]+}}@or_sext_sext_2_use1
4452+ ; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
4453+ ; CHECK-NEXT: [[SX:%.*]] = sext i8 [[X]] to i16
4454+ ; CHECK-NEXT: call void @use_i16(i16 [[SX]])
4455+ ; CHECK-NEXT: [[R1:%.*]] = or i8 [[X]], [[Y]]
4456+ ; CHECK-NEXT: [[R:%.*]] = sext i8 [[R1]] to i16
4457+ ; CHECK-NEXT: ret i16 [[R]]
4458+ ;
4459+ %sx = sext i8 %x to i16
4460+ call void @use_i16 (i16 %sx )
4461+ %sy = sext i8 %y to i16
4462+ %r = or i16 %sx , %sy
4463+ ret i16 %r
4464+ }
4465+
43194466define i16 @xor_sext_sext (i8 %x , i4 %y ) {
43204467; CHECK-LABEL: define {{[^@]+}}@xor_sext_sext
43214468; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
43224469; CHECK-NEXT: [[TMP1:%.*]] = sext i4 [[Y]] to i8
4323- ; CHECK-NEXT: [[TMP2 :%.*]] = xor i8 [[X]], [[TMP1]]
4324- ; CHECK-NEXT: [[R:%.*]] = sext i8 [[TMP2 ]] to i16
4470+ ; CHECK-NEXT: [[R1 :%.*]] = xor i8 [[X]], [[TMP1]]
4471+ ; CHECK-NEXT: [[R:%.*]] = sext i8 [[R1 ]] to i16
43254472; CHECK-NEXT: ret i16 [[R]]
43264473;
43274474 %sx = sext i8 %x to i16
@@ -4330,6 +4477,35 @@ define i16 @xor_sext_sext(i8 %x, i4 %y) {
43304477 ret i16 %r
43314478}
43324479
4480+ define i16 @xor_sext_sext_2 (i8 %x , i8 %y ) {
4481+ ; CHECK-LABEL: define {{[^@]+}}@xor_sext_sext_2
4482+ ; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
4483+ ; CHECK-NEXT: [[R1:%.*]] = xor i8 [[X]], [[Y]]
4484+ ; CHECK-NEXT: [[R:%.*]] = sext i8 [[R1]] to i16
4485+ ; CHECK-NEXT: ret i16 [[R]]
4486+ ;
4487+ %sx = sext i8 %x to i16
4488+ %sy = sext i8 %y to i16
4489+ %r = xor i16 %sx , %sy
4490+ ret i16 %r
4491+ }
4492+
4493+ define i16 @xor_sext_sext_2_use1 (i8 %x , i8 %y ) {
4494+ ; CHECK-LABEL: define {{[^@]+}}@xor_sext_sext_2_use1
4495+ ; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
4496+ ; CHECK-NEXT: [[SX:%.*]] = sext i8 [[X]] to i16
4497+ ; CHECK-NEXT: call void @use_i16(i16 [[SX]])
4498+ ; CHECK-NEXT: [[R1:%.*]] = xor i8 [[X]], [[Y]]
4499+ ; CHECK-NEXT: [[R:%.*]] = sext i8 [[R1]] to i16
4500+ ; CHECK-NEXT: ret i16 [[R]]
4501+ ;
4502+ %sx = sext i8 %x to i16
4503+ call void @use_i16 (i16 %sx )
4504+ %sy = sext i8 %y to i16
4505+ %r = xor i16 %sx , %sy
4506+ ret i16 %r
4507+ }
4508+
43334509; negative test - mismatched casts
43344510
43354511define i16 @and_zext_sext (i8 %x , i4 %y ) {
@@ -4364,6 +4540,24 @@ define i32 @and_zext_zext_use1(i8 %x, i4 %y) {
43644540 ret i32 %r
43654541}
43664542
4543+ define i32 @and_zext_zext_use2 (i8 %x , i8 %y ) {
4544+ ; CHECK-LABEL: define {{[^@]+}}@and_zext_zext_use2
4545+ ; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
4546+ ; CHECK-NEXT: [[ZX:%.*]] = zext i8 [[X]] to i32
4547+ ; CHECK-NEXT: call void @use(i32 [[ZX]])
4548+ ; CHECK-NEXT: [[ZY:%.*]] = zext i8 [[Y]] to i32
4549+ ; CHECK-NEXT: call void @use(i32 [[ZY]])
4550+ ; CHECK-NEXT: [[R:%.*]] = and i32 [[ZX]], [[ZY]]
4551+ ; CHECK-NEXT: ret i32 [[R]]
4552+ ;
4553+ %zx = zext i8 %x to i32
4554+ call void @use (i32 %zx )
4555+ %zy = zext i8 %y to i32
4556+ call void @use (i32 %zy )
4557+ %r = and i32 %zx , %zy
4558+ ret i32 %r
4559+ }
4560+
43674561; negative test - don't create an extra instruction
43684562
43694563define i32 @or_sext_sext_use1 (i8 %x , i4 %y ) {
@@ -4382,6 +4576,24 @@ define i32 @or_sext_sext_use1(i8 %x, i4 %y) {
43824576 ret i32 %r
43834577}
43844578
4579+ define i32 @or_sext_sext_use2 (i8 %x , i8 %y ) {
4580+ ; CHECK-LABEL: define {{[^@]+}}@or_sext_sext_use2
4581+ ; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
4582+ ; CHECK-NEXT: [[SX:%.*]] = sext i8 [[X]] to i32
4583+ ; CHECK-NEXT: call void @use(i32 [[SX]])
4584+ ; CHECK-NEXT: [[SY:%.*]] = sext i8 [[Y]] to i32
4585+ ; CHECK-NEXT: call void @use(i32 [[SY]])
4586+ ; CHECK-NEXT: [[R:%.*]] = or i32 [[SX]], [[SY]]
4587+ ; CHECK-NEXT: ret i32 [[R]]
4588+ ;
4589+ %sx = sext i8 %x to i32
4590+ call void @use (i32 %sx )
4591+ %sy = sext i8 %y to i32
4592+ call void @use (i32 %sy )
4593+ %r = or i32 %sx , %sy
4594+ ret i32 %r
4595+ }
4596+
43854597define i1 @PR56294 (i8 %x ) {
43864598; CHECK-LABEL: define {{[^@]+}}@PR56294
43874599; CHECK-SAME: (i8 [[X:%.*]]) {
0 commit comments