@@ -253,12 +253,50 @@ define <3 x i1> @t15_const_lshr_shl_ne_vec_undef6(<3 x i32> %x, <3 x i32> %y) {
253253 ret <3 x i1 > %t3
254254}
255255
256+ ; Commutativity tests
257+
258+ declare i32 @gen32 ()
259+
260+ define i1 @t16_commutativity0 (i32 %x ) {
261+ ; CHECK-LABEL: @t16_commutativity0(
262+ ; CHECK-NEXT: [[Y:%.*]] = call i32 @gen32()
263+ ; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X:%.*]], 1
264+ ; CHECK-NEXT: [[T1:%.*]] = shl i32 [[Y]], 1
265+ ; CHECK-NEXT: [[T2:%.*]] = and i32 [[T1]], [[T0]]
266+ ; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 0
267+ ; CHECK-NEXT: ret i1 [[T3]]
268+ ;
269+ %y = call i32 @gen32 ()
270+ %t0 = lshr i32 %x , 1
271+ %t1 = shl i32 %y , 1
272+ %t2 = and i32 %t1 , %t0
273+ %t3 = icmp ne i32 %t2 , 0
274+ ret i1 %t3
275+ }
276+
277+ define i1 @t17_commutativity1 (i32 %y ) {
278+ ; CHECK-LABEL: @t17_commutativity1(
279+ ; CHECK-NEXT: [[X:%.*]] = call i32 @gen32()
280+ ; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X]], 1
281+ ; CHECK-NEXT: [[T1:%.*]] = shl i32 [[Y:%.*]], 1
282+ ; CHECK-NEXT: [[T2:%.*]] = and i32 [[T0]], [[T1]]
283+ ; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 0
284+ ; CHECK-NEXT: ret i1 [[T3]]
285+ ;
286+ %x = call i32 @gen32 ()
287+ %t0 = lshr i32 %x , 1
288+ %t1 = shl i32 %y , 1
289+ %t2 = and i32 %t0 , %t1 ; "swapped"
290+ %t3 = icmp ne i32 %t2 , 0
291+ ret i1 %t3
292+ }
293+
256294; One-use tests
257295
258296declare void @use32 (i32 )
259297
260- define i1 @t16_const_oneuse0 (i32 %x , i32 %y ) {
261- ; CHECK-LABEL: @t16_const_oneuse0 (
298+ define i1 @t18_const_oneuse0 (i32 %x , i32 %y ) {
299+ ; CHECK-LABEL: @t18_const_oneuse0 (
262300; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X:%.*]], 1
263301; CHECK-NEXT: call void @use32(i32 [[T0]])
264302; CHECK-NEXT: [[T1:%.*]] = shl i32 [[Y:%.*]], 1
@@ -273,8 +311,8 @@ define i1 @t16_const_oneuse0(i32 %x, i32 %y) {
273311 %t3 = icmp ne i32 %t2 , 0
274312 ret i1 %t3
275313}
276- define i1 @t17_const_oneuse1 (i32 %x , i32 %y ) {
277- ; CHECK-LABEL: @t17_const_oneuse1 (
314+ define i1 @t19_const_oneuse1 (i32 %x , i32 %y ) {
315+ ; CHECK-LABEL: @t19_const_oneuse1 (
278316; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X:%.*]], 1
279317; CHECK-NEXT: [[T1:%.*]] = shl i32 [[Y:%.*]], 1
280318; CHECK-NEXT: call void @use32(i32 [[T1]])
@@ -289,8 +327,8 @@ define i1 @t17_const_oneuse1(i32 %x, i32 %y) {
289327 %t3 = icmp ne i32 %t2 , 0
290328 ret i1 %t3
291329}
292- define i1 @t18_const_oneuse2 (i32 %x , i32 %y ) {
293- ; CHECK-LABEL: @t18_const_oneuse2 (
330+ define i1 @t20_const_oneuse2 (i32 %x , i32 %y ) {
331+ ; CHECK-LABEL: @t20_const_oneuse2 (
294332; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X:%.*]], 1
295333; CHECK-NEXT: [[T1:%.*]] = shl i32 [[Y:%.*]], 1
296334; CHECK-NEXT: [[T2:%.*]] = and i32 [[T1]], [[T0]]
@@ -305,8 +343,8 @@ define i1 @t18_const_oneuse2(i32 %x, i32 %y) {
305343 %t3 = icmp ne i32 %t2 , 0
306344 ret i1 %t3
307345}
308- define i1 @t19_const_oneuse3 (i32 %x , i32 %y ) {
309- ; CHECK-LABEL: @t19_const_oneuse3 (
346+ define i1 @t21_const_oneuse3 (i32 %x , i32 %y ) {
347+ ; CHECK-LABEL: @t21_const_oneuse3 (
310348; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X:%.*]], 1
311349; CHECK-NEXT: call void @use32(i32 [[T0]])
312350; CHECK-NEXT: [[T1:%.*]] = shl i32 [[Y:%.*]], 1
@@ -323,8 +361,8 @@ define i1 @t19_const_oneuse3(i32 %x, i32 %y) {
323361 %t3 = icmp ne i32 %t2 , 0
324362 ret i1 %t3
325363}
326- define i1 @t20_const_oneuse4 (i32 %x , i32 %y ) {
327- ; CHECK-LABEL: @t20_const_oneuse4 (
364+ define i1 @t22_const_oneuse4 (i32 %x , i32 %y ) {
365+ ; CHECK-LABEL: @t22_const_oneuse4 (
328366; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X:%.*]], 1
329367; CHECK-NEXT: call void @use32(i32 [[T0]])
330368; CHECK-NEXT: [[T1:%.*]] = shl i32 [[Y:%.*]], 1
@@ -341,8 +379,8 @@ define i1 @t20_const_oneuse4(i32 %x, i32 %y) {
341379 %t3 = icmp ne i32 %t2 , 0
342380 ret i1 %t3
343381}
344- define i1 @t21_const_oneuse5 (i32 %x , i32 %y ) {
345- ; CHECK-LABEL: @t21_const_oneuse5 (
382+ define i1 @t23_const_oneuse5 (i32 %x , i32 %y ) {
383+ ; CHECK-LABEL: @t23_const_oneuse5 (
346384; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X:%.*]], 1
347385; CHECK-NEXT: [[T1:%.*]] = shl i32 [[Y:%.*]], 1
348386; CHECK-NEXT: call void @use32(i32 [[T1]])
@@ -359,8 +397,8 @@ define i1 @t21_const_oneuse5(i32 %x, i32 %y) {
359397 %t3 = icmp ne i32 %t2 , 0
360398 ret i1 %t3
361399}
362- define i1 @t22_const_oneuse6 (i32 %x , i32 %y ) {
363- ; CHECK-LABEL: @t22_const_oneuse6 (
400+ define i1 @t24_const_oneuse6 (i32 %x , i32 %y ) {
401+ ; CHECK-LABEL: @t24_const_oneuse6 (
364402; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X:%.*]], 1
365403; CHECK-NEXT: call void @use32(i32 [[T0]])
366404; CHECK-NEXT: [[T1:%.*]] = shl i32 [[Y:%.*]], 1
@@ -380,8 +418,8 @@ define i1 @t22_const_oneuse6(i32 %x, i32 %y) {
380418 ret i1 %t3
381419}
382420
383- define i1 @t23_var_oneuse0 (i32 %x , i32 %y , i32 %shamt0 , i32 %shamt1 ) {
384- ; CHECK-LABEL: @t23_var_oneuse0 (
421+ define i1 @t25_var_oneuse0 (i32 %x , i32 %y , i32 %shamt0 , i32 %shamt1 ) {
422+ ; CHECK-LABEL: @t25_var_oneuse0 (
385423; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X:%.*]], [[SHAMT0:%.*]]
386424; CHECK-NEXT: call void @use32(i32 [[T0]])
387425; CHECK-NEXT: [[T1:%.*]] = shl i32 [[Y:%.*]], [[SHAMT1:%.*]]
@@ -396,8 +434,8 @@ define i1 @t23_var_oneuse0(i32 %x, i32 %y, i32 %shamt0, i32 %shamt1) {
396434 %t3 = icmp ne i32 %t2 , 0
397435 ret i1 %t3
398436}
399- define i1 @t24_var_oneuse1 (i32 %x , i32 %y , i32 %shamt0 , i32 %shamt1 ) {
400- ; CHECK-LABEL: @t24_var_oneuse1 (
437+ define i1 @t26_var_oneuse1 (i32 %x , i32 %y , i32 %shamt0 , i32 %shamt1 ) {
438+ ; CHECK-LABEL: @t26_var_oneuse1 (
401439; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X:%.*]], [[SHAMT0:%.*]]
402440; CHECK-NEXT: [[T1:%.*]] = shl i32 [[Y:%.*]], [[SHAMT1:%.*]]
403441; CHECK-NEXT: call void @use32(i32 [[T1]])
@@ -412,8 +450,8 @@ define i1 @t24_var_oneuse1(i32 %x, i32 %y, i32 %shamt0, i32 %shamt1) {
412450 %t3 = icmp ne i32 %t2 , 0
413451 ret i1 %t3
414452}
415- define i1 @t25_var_oneuse2 (i32 %x , i32 %y , i32 %shamt0 , i32 %shamt1 ) {
416- ; CHECK-LABEL: @t25_var_oneuse2 (
453+ define i1 @t27_var_oneuse2 (i32 %x , i32 %y , i32 %shamt0 , i32 %shamt1 ) {
454+ ; CHECK-LABEL: @t27_var_oneuse2 (
417455; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X:%.*]], [[SHAMT0:%.*]]
418456; CHECK-NEXT: [[T1:%.*]] = shl i32 [[Y:%.*]], [[SHAMT1:%.*]]
419457; CHECK-NEXT: [[T2:%.*]] = and i32 [[T1]], [[T0]]
@@ -428,8 +466,8 @@ define i1 @t25_var_oneuse2(i32 %x, i32 %y, i32 %shamt0, i32 %shamt1) {
428466 %t3 = icmp ne i32 %t2 , 0
429467 ret i1 %t3
430468}
431- define i1 @t26_var_oneuse3 (i32 %x , i32 %y , i32 %shamt0 , i32 %shamt1 ) {
432- ; CHECK-LABEL: @t26_var_oneuse3 (
469+ define i1 @t28_var_oneuse3 (i32 %x , i32 %y , i32 %shamt0 , i32 %shamt1 ) {
470+ ; CHECK-LABEL: @t28_var_oneuse3 (
433471; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X:%.*]], [[SHAMT0:%.*]]
434472; CHECK-NEXT: call void @use32(i32 [[T0]])
435473; CHECK-NEXT: [[T1:%.*]] = shl i32 [[Y:%.*]], [[SHAMT1:%.*]]
@@ -446,8 +484,8 @@ define i1 @t26_var_oneuse3(i32 %x, i32 %y, i32 %shamt0, i32 %shamt1) {
446484 %t3 = icmp ne i32 %t2 , 0
447485 ret i1 %t3
448486}
449- define i1 @t27_var_oneuse4 (i32 %x , i32 %y , i32 %shamt0 , i32 %shamt1 ) {
450- ; CHECK-LABEL: @t27_var_oneuse4 (
487+ define i1 @t29_var_oneuse4 (i32 %x , i32 %y , i32 %shamt0 , i32 %shamt1 ) {
488+ ; CHECK-LABEL: @t29_var_oneuse4 (
451489; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X:%.*]], [[SHAMT0:%.*]]
452490; CHECK-NEXT: call void @use32(i32 [[T0]])
453491; CHECK-NEXT: [[T1:%.*]] = shl i32 [[Y:%.*]], [[SHAMT1:%.*]]
@@ -464,8 +502,8 @@ define i1 @t27_var_oneuse4(i32 %x, i32 %y, i32 %shamt0, i32 %shamt1) {
464502 %t3 = icmp ne i32 %t2 , 0
465503 ret i1 %t3
466504}
467- define i1 @t28_var_oneuse5 (i32 %x , i32 %y , i32 %shamt0 , i32 %shamt1 ) {
468- ; CHECK-LABEL: @t28_var_oneuse5 (
505+ define i1 @t30_var_oneuse5 (i32 %x , i32 %y , i32 %shamt0 , i32 %shamt1 ) {
506+ ; CHECK-LABEL: @t30_var_oneuse5 (
469507; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X:%.*]], [[SHAMT0:%.*]]
470508; CHECK-NEXT: [[T1:%.*]] = shl i32 [[Y:%.*]], [[SHAMT1:%.*]]
471509; CHECK-NEXT: call void @use32(i32 [[T1]])
@@ -482,8 +520,8 @@ define i1 @t28_var_oneuse5(i32 %x, i32 %y, i32 %shamt0, i32 %shamt1) {
482520 %t3 = icmp ne i32 %t2 , 0
483521 ret i1 %t3
484522}
485- define i1 @t29_var_oneuse6 (i32 %x , i32 %y , i32 %shamt0 , i32 %shamt1 ) {
486- ; CHECK-LABEL: @t29_var_oneuse6 (
523+ define i1 @t31_var_oneuse6 (i32 %x , i32 %y , i32 %shamt0 , i32 %shamt1 ) {
524+ ; CHECK-LABEL: @t31_var_oneuse6 (
487525; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X:%.*]], [[SHAMT0:%.*]]
488526; CHECK-NEXT: call void @use32(i32 [[T0]])
489527; CHECK-NEXT: [[T1:%.*]] = shl i32 [[Y:%.*]], [[SHAMT1:%.*]]
@@ -503,9 +541,85 @@ define i1 @t29_var_oneuse6(i32 %x, i32 %y, i32 %shamt0, i32 %shamt1) {
503541 ret i1 %t3
504542}
505543
544+ ; Commutativity with extra uses
545+
546+ define i1 @t32_commutativity0_oneuse0 (i32 %x ) {
547+ ; CHECK-LABEL: @t32_commutativity0_oneuse0(
548+ ; CHECK-NEXT: [[Y:%.*]] = call i32 @gen32()
549+ ; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X:%.*]], 1
550+ ; CHECK-NEXT: call void @use32(i32 [[T0]])
551+ ; CHECK-NEXT: [[T1:%.*]] = shl i32 [[Y]], 1
552+ ; CHECK-NEXT: [[T2:%.*]] = and i32 [[T1]], [[T0]]
553+ ; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 0
554+ ; CHECK-NEXT: ret i1 [[T3]]
555+ ;
556+ %y = call i32 @gen32 ()
557+ %t0 = lshr i32 %x , 1
558+ call void @use32 (i32 %t0 )
559+ %t1 = shl i32 %y , 1
560+ %t2 = and i32 %t1 , %t0
561+ %t3 = icmp ne i32 %t2 , 0
562+ ret i1 %t3
563+ }
564+ define i1 @t33_commutativity0_oneuse1 (i32 %x ) {
565+ ; CHECK-LABEL: @t33_commutativity0_oneuse1(
566+ ; CHECK-NEXT: [[Y:%.*]] = call i32 @gen32()
567+ ; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X:%.*]], 1
568+ ; CHECK-NEXT: [[T1:%.*]] = shl i32 [[Y]], 1
569+ ; CHECK-NEXT: call void @use32(i32 [[T1]])
570+ ; CHECK-NEXT: [[T2:%.*]] = and i32 [[T1]], [[T0]]
571+ ; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 0
572+ ; CHECK-NEXT: ret i1 [[T3]]
573+ ;
574+ %y = call i32 @gen32 ()
575+ %t0 = lshr i32 %x , 1
576+ %t1 = shl i32 %y , 1
577+ call void @use32 (i32 %t1 )
578+ %t2 = and i32 %t1 , %t0
579+ %t3 = icmp ne i32 %t2 , 0
580+ ret i1 %t3
581+ }
582+
583+ define i1 @t34_commutativity1_oneuse0 (i32 %y ) {
584+ ; CHECK-LABEL: @t34_commutativity1_oneuse0(
585+ ; CHECK-NEXT: [[X:%.*]] = call i32 @gen32()
586+ ; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X]], 1
587+ ; CHECK-NEXT: call void @use32(i32 [[T0]])
588+ ; CHECK-NEXT: [[T1:%.*]] = shl i32 [[Y:%.*]], 1
589+ ; CHECK-NEXT: [[T2:%.*]] = and i32 [[T0]], [[T1]]
590+ ; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 0
591+ ; CHECK-NEXT: ret i1 [[T3]]
592+ ;
593+ %x = call i32 @gen32 ()
594+ %t0 = lshr i32 %x , 1
595+ call void @use32 (i32 %t0 )
596+ %t1 = shl i32 %y , 1
597+ %t2 = and i32 %t0 , %t1 ; "swapped"
598+ %t3 = icmp ne i32 %t2 , 0
599+ ret i1 %t3
600+ }
601+ define i1 @t35_commutativity1_oneuse1 (i32 %y ) {
602+ ; CHECK-LABEL: @t35_commutativity1_oneuse1(
603+ ; CHECK-NEXT: [[X:%.*]] = call i32 @gen32()
604+ ; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X]], 1
605+ ; CHECK-NEXT: [[T1:%.*]] = shl i32 [[Y:%.*]], 1
606+ ; CHECK-NEXT: call void @use32(i32 [[T1]])
607+ ; CHECK-NEXT: [[T2:%.*]] = and i32 [[T0]], [[T1]]
608+ ; CHECK-NEXT: [[T3:%.*]] = icmp ne i32 [[T2]], 0
609+ ; CHECK-NEXT: ret i1 [[T3]]
610+ ;
611+ %x = call i32 @gen32 ()
612+ %t0 = lshr i32 %x , 1
613+ %t1 = shl i32 %y , 1
614+ call void @use32 (i32 %t1 )
615+ %t2 = and i32 %t0 , %t1 ; "swapped"
616+ %t3 = icmp ne i32 %t2 , 0
617+ ret i1 %t3
618+ }
619+
506620; Negative tests
507- define <2 x i1 > @n20_overshift (<2 x i32 > %x , <2 x i32 > %y ) {
508- ; CHECK-LABEL: @n20_overshift (
621+ define <2 x i1 > @n36_overshift (<2 x i32 > %x , <2 x i32 > %y ) {
622+ ; CHECK-LABEL: @n36_overshift (
509623; CHECK-NEXT: [[T0:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 15, i32 1>
510624; CHECK-NEXT: [[T1:%.*]] = shl <2 x i32> [[Y:%.*]], <i32 17, i32 1>
511625; CHECK-NEXT: [[T2:%.*]] = and <2 x i32> [[T1]], [[T0]]
0 commit comments