2
2
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
3
4
4
declare void @use (i32 )
5
+ declare void @use_i16 (i8 )
6
+ declare void @use_2xi16 (<2 x i16 >)
5
7
declare void @use_i8 (i8 )
6
8
declare void @use_i1 (i1 )
7
9
@@ -4250,8 +4252,8 @@ define i16 @and_zext_zext(i8 %x, i4 %y) {
4250
4252
; CHECK-LABEL: define {{[^@]+}}@and_zext_zext
4251
4253
; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
4252
4254
; 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
4255
4257
; CHECK-NEXT: ret i16 [[R]]
4256
4258
;
4257
4259
%zx = zext i8 %x to i16
@@ -4260,12 +4262,41 @@ define i16 @and_zext_zext(i8 %x, i4 %y) {
4260
4262
ret i16 %r
4261
4263
}
4262
4264
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
+
4263
4294
define i16 @or_zext_zext (i8 %x , i4 %y ) {
4264
4295
; CHECK-LABEL: define {{[^@]+}}@or_zext_zext
4265
4296
; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
4266
4297
; 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
4269
4300
; CHECK-NEXT: ret i16 [[R]]
4270
4301
;
4271
4302
%zx = zext i8 %x to i16
@@ -4274,12 +4305,41 @@ define i16 @or_zext_zext(i8 %x, i4 %y) {
4274
4305
ret i16 %r
4275
4306
}
4276
4307
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
+
4277
4337
define <2 x i16 > @xor_zext_zext (<2 x i8 > %x , <2 x i4 > %y ) {
4278
4338
; CHECK-LABEL: define {{[^@]+}}@xor_zext_zext
4279
4339
; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i4> [[Y:%.*]]) {
4280
4340
; 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>
4283
4343
; CHECK-NEXT: ret <2 x i16> [[R]]
4284
4344
;
4285
4345
%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) {
4288
4348
ret <2 x i16 > %r
4289
4349
}
4290
4350
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
+
4291
4380
define i16 @and_sext_sext (i8 %x , i4 %y ) {
4292
4381
; CHECK-LABEL: define {{[^@]+}}@and_sext_sext
4293
4382
; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
4294
4383
; 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
4297
4386
; CHECK-NEXT: ret i16 [[R]]
4298
4387
;
4299
4388
%sx = sext i8 %x to i16
@@ -4302,12 +4391,41 @@ define i16 @and_sext_sext(i8 %x, i4 %y) {
4302
4391
ret i16 %r
4303
4392
}
4304
4393
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
+
4305
4423
define i16 @or_sext_sext (i8 %x , i4 %y ) {
4306
4424
; CHECK-LABEL: define {{[^@]+}}@or_sext_sext
4307
4425
; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
4308
4426
; 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
4311
4429
; CHECK-NEXT: ret i16 [[R]]
4312
4430
;
4313
4431
%sx = sext i8 %x to i16
@@ -4316,12 +4434,41 @@ define i16 @or_sext_sext(i8 %x, i4 %y) {
4316
4434
ret i16 %r
4317
4435
}
4318
4436
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
+
4319
4466
define i16 @xor_sext_sext (i8 %x , i4 %y ) {
4320
4467
; CHECK-LABEL: define {{[^@]+}}@xor_sext_sext
4321
4468
; CHECK-SAME: (i8 [[X:%.*]], i4 [[Y:%.*]]) {
4322
4469
; 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
4325
4472
; CHECK-NEXT: ret i16 [[R]]
4326
4473
;
4327
4474
%sx = sext i8 %x to i16
@@ -4330,6 +4477,35 @@ define i16 @xor_sext_sext(i8 %x, i4 %y) {
4330
4477
ret i16 %r
4331
4478
}
4332
4479
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
+
4333
4509
; negative test - mismatched casts
4334
4510
4335
4511
define i16 @and_zext_sext (i8 %x , i4 %y ) {
@@ -4364,6 +4540,24 @@ define i32 @and_zext_zext_use1(i8 %x, i4 %y) {
4364
4540
ret i32 %r
4365
4541
}
4366
4542
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
+
4367
4561
; negative test - don't create an extra instruction
4368
4562
4369
4563
define i32 @or_sext_sext_use1 (i8 %x , i4 %y ) {
@@ -4382,6 +4576,24 @@ define i32 @or_sext_sext_use1(i8 %x, i4 %y) {
4382
4576
ret i32 %r
4383
4577
}
4384
4578
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
+
4385
4597
define i1 @PR56294 (i8 %x ) {
4386
4598
; CHECK-LABEL: define {{[^@]+}}@PR56294
4387
4599
; CHECK-SAME: (i8 [[X:%.*]]) {
0 commit comments