1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4define i32 @select_of_symmetric_selects(i32 %a, i32 %b, i1 %c1, i1 %c2) { 5; CHECK-LABEL: @select_of_symmetric_selects( 6; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[C1:%.*]], [[C2:%.*]] 7; CHECK-NEXT: [[RET:%.*]] = select i1 [[TMP1]], i32 [[B:%.*]], i32 [[A:%.*]] 8; CHECK-NEXT: ret i32 [[RET]] 9; 10 %sel1 = select i1 %c1, i32 %a, i32 %b 11 %sel2 = select i1 %c1, i32 %b, i32 %a 12 %ret = select i1 %c2, i32 %sel1, i32 %sel2 13 ret i32 %ret 14} 15 16define i32 @select_of_symmetric_selects_negative1(i32 %a, i32 %b, i1 %c1, i1 %c2) { 17; CHECK-LABEL: @select_of_symmetric_selects_negative1( 18; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[C1:%.*]], i32 [[A:%.*]], i32 [[B:%.*]] 19; CHECK-NEXT: [[RET:%.*]] = select i1 [[C2:%.*]], i32 [[SEL1]], i32 [[A]] 20; CHECK-NEXT: ret i32 [[RET]] 21; 22 %sel1 = select i1 %c1, i32 %a, i32 %b 23 %sel2 = select i1 %c2, i32 %b, i32 %a 24 %ret = select i1 %c2, i32 %sel1, i32 %sel2 25 ret i32 %ret 26} 27 28define i32 @select_of_symmetric_selects_negative2(i32 %a, i32 %b, i32 %c, i1 %c1, i1 %c2) { 29; CHECK-LABEL: @select_of_symmetric_selects_negative2( 30; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[C1:%.*]], i32 [[A:%.*]], i32 [[B:%.*]] 31; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[C1]], i32 [[B]], i32 [[C:%.*]] 32; CHECK-NEXT: [[RET:%.*]] = select i1 [[C2:%.*]], i32 [[SEL1]], i32 [[SEL2]] 33; CHECK-NEXT: ret i32 [[RET]] 34; 35 %sel1 = select i1 %c1, i32 %a, i32 %b 36 %sel2 = select i1 %c1, i32 %b, i32 %c 37 %ret = select i1 %c2, i32 %sel1, i32 %sel2 38 ret i32 %ret 39} 40 41declare void @use(i32) 42 43define i32 @select_of_symmetric_selects_multi_use1(i32 %a, i32 %b, i1 %c1, i1 %c2) { 44; CHECK-LABEL: @select_of_symmetric_selects_multi_use1( 45; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[C1:%.*]], i32 [[A:%.*]], i32 [[B:%.*]] 46; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[C1]], i32 [[B]], i32 [[A]] 47; CHECK-NEXT: call void @use(i32 [[SEL2]]) 48; CHECK-NEXT: [[RET:%.*]] = select i1 [[C2:%.*]], i32 [[SEL1]], i32 [[SEL2]] 49; CHECK-NEXT: ret i32 [[RET]] 50; 51 %sel1 = select i1 %c1, i32 %a, i32 %b 52 %sel2 = select i1 %c1, i32 %b, i32 %a 53 call void @use(i32 %sel2) 54 %ret = select i1 %c2, i32 %sel1, i32 %sel2 55 ret i32 %ret 56} 57 58define i32 @select_of_symmetric_selects_multi_use2(i32 %a, i32 %b, i1 %c1, i1 %c2) { 59; CHECK-LABEL: @select_of_symmetric_selects_multi_use2( 60; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[C1:%.*]], i32 [[A:%.*]], i32 [[B:%.*]] 61; CHECK-NEXT: call void @use(i32 [[SEL1]]) 62; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[C1]], i32 [[B]], i32 [[A]] 63; CHECK-NEXT: call void @use(i32 [[SEL2]]) 64; CHECK-NEXT: [[RET:%.*]] = select i1 [[C2:%.*]], i32 [[SEL1]], i32 [[SEL2]] 65; CHECK-NEXT: ret i32 [[RET]] 66; 67 %sel1 = select i1 %c1, i32 %a, i32 %b 68 call void @use(i32 %sel1) 69 %sel2 = select i1 %c1, i32 %b, i32 %a 70 call void @use(i32 %sel2) 71 %ret = select i1 %c2, i32 %sel1, i32 %sel2 72 ret i32 %ret 73} 74 75define i32 @select_of_symmetric_selects_commuted(i32 %a, i32 %b, i1 %c1, i1 %c2) { 76; CHECK-LABEL: @select_of_symmetric_selects_commuted( 77; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[C1:%.*]], [[C2:%.*]] 78; CHECK-NEXT: [[RET:%.*]] = select i1 [[TMP1]], i32 [[A:%.*]], i32 [[B:%.*]] 79; CHECK-NEXT: ret i32 [[RET]] 80; 81 %sel1 = select i1 %c1, i32 %a, i32 %b 82 %sel2 = select i1 %c1, i32 %b, i32 %a 83 %ret = select i1 %c2, i32 %sel2, i32 %sel1 84 ret i32 %ret 85} 86 87define <4 x i32> @select_of_symmetric_selects_vector1(<4 x i32> %a, <4 x i32> %b, i1 %c1, i1 %c2) { 88; CHECK-LABEL: @select_of_symmetric_selects_vector1( 89; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[C1:%.*]], [[C2:%.*]] 90; CHECK-NEXT: [[RET:%.*]] = select i1 [[TMP1]], <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]] 91; CHECK-NEXT: ret <4 x i32> [[RET]] 92; 93 %sel1 = select i1 %c1, <4 x i32> %a, <4 x i32> %b 94 %sel2 = select i1 %c1, <4 x i32> %b, <4 x i32> %a 95 %ret = select i1 %c2, <4 x i32> %sel2, <4 x i32> %sel1 96 ret <4 x i32> %ret 97} 98 99define <4 x i32> @select_of_symmetric_selects_vector2(<4 x i32> %a, <4 x i32> %b, <4 x i1> %c1, <4 x i1> %c2) { 100; CHECK-LABEL: @select_of_symmetric_selects_vector2( 101; CHECK-NEXT: [[TMP1:%.*]] = xor <4 x i1> [[C1:%.*]], [[C2:%.*]] 102; CHECK-NEXT: [[RET:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]] 103; CHECK-NEXT: ret <4 x i32> [[RET]] 104; 105 %sel1 = select <4 x i1> %c1, <4 x i32> %a, <4 x i32> %b 106 %sel2 = select <4 x i1> %c1, <4 x i32> %b, <4 x i32> %a 107 %ret = select <4 x i1> %c2, <4 x i32> %sel2, <4 x i32> %sel1 108 ret <4 x i32> %ret 109} 110 111define <2 x i32> @select_of_symmetric_selects_vector3(<2 x i32> %a, <2 x i32> %b, <2 x i1> %c1, i1 %c2) { 112; CHECK-LABEL: @select_of_symmetric_selects_vector3( 113; CHECK-NEXT: [[SEL1:%.*]] = select <2 x i1> [[C1:%.*]], <2 x i32> [[A:%.*]], <2 x i32> [[B:%.*]] 114; CHECK-NEXT: [[SEL2:%.*]] = select <2 x i1> [[C1]], <2 x i32> [[B]], <2 x i32> [[A]] 115; CHECK-NEXT: [[RET:%.*]] = select i1 [[C2:%.*]], <2 x i32> [[SEL1]], <2 x i32> [[SEL2]] 116; CHECK-NEXT: ret <2 x i32> [[RET]] 117; 118 %sel1 = select <2 x i1> %c1, <2 x i32> %a, <2 x i32> %b 119 %sel2 = select <2 x i1> %c1, <2 x i32> %b, <2 x i32> %a 120 %ret = select i1 %c2, <2 x i32> %sel1, <2 x i32> %sel2 121 ret <2 x i32> %ret 122 } 123