187 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4declare void @use(i32)5define i1 @cmpeq_xor_cst1(i32 %a, i32 %b) {6; CHECK-LABEL: @cmpeq_xor_cst1(7; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]8; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 109; CHECK-NEXT: ret i1 [[CMP]]10;11 %c = xor i32 %a, 1012 %cmp = icmp eq i32 %c, %b13 ret i1 %cmp14}15 16define i1 @cmpeq_xor_cst2(i32 %a, i32 %b) {17; CHECK-LABEL: @cmpeq_xor_cst2(18; CHECK-NEXT: [[C:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]19; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 1020; CHECK-NEXT: ret i1 [[CMP]]21;22 %c = xor i32 %a, %b23 %cmp = icmp eq i32 %c, 1024 ret i1 %cmp25}26 27define i1 @cmpeq_xor_cst3(i32 %a, i32 %b) {28; CHECK-LABEL: @cmpeq_xor_cst3(29; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]30; CHECK-NEXT: ret i1 [[CMP]]31;32 %c = xor i32 %a, 1033 %d = xor i32 %b, 1034 %cmp = icmp eq i32 %c, %d35 ret i1 %cmp36}37 38define i1 @cmpne_xor_cst1(i32 %a, i32 %b) {39; CHECK-LABEL: @cmpne_xor_cst1(40; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]41; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 1042; CHECK-NEXT: ret i1 [[CMP]]43;44 %c = xor i32 %a, 1045 %cmp = icmp ne i32 %c, %b46 ret i1 %cmp47}48 49define i1 @cmpne_xor_cst2(i32 %a, i32 %b) {50; CHECK-LABEL: @cmpne_xor_cst2(51; CHECK-NEXT: [[C:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]52; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[C]], 1053; CHECK-NEXT: ret i1 [[CMP]]54;55 %c = xor i32 %a, %b56 %cmp = icmp ne i32 %c, 1057 ret i1 %cmp58}59 60define i1 @cmpne_xor_cst3(i32 %a, i32 %b) {61; CHECK-LABEL: @cmpne_xor_cst3(62; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]63; CHECK-NEXT: ret i1 [[CMP]]64;65 %c = xor i32 %a, 1066 %d = xor i32 %b, 1067 %cmp = icmp ne i32 %c, %d68 ret i1 %cmp69}70 71define i1 @cmpeq_xor_cst1_multiuse(i32 %a, i32 %b) {72; CHECK-LABEL: @cmpeq_xor_cst1_multiuse(73; CHECK-NEXT: [[C:%.*]] = xor i32 [[A:%.*]], 1074; CHECK-NEXT: call void @use(i32 [[C]])75; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], [[B:%.*]]76; CHECK-NEXT: ret i1 [[CMP]]77;78 %c = xor i32 %a, 1079 call void @use(i32 %c)80 %cmp = icmp eq i32 %c, %b81 ret i1 %cmp82}83 84define i1 @cmpeq_xor_cst1_commuted(i32 %a, i32 %b) {85; CHECK-LABEL: @cmpeq_xor_cst1_commuted(86; CHECK-NEXT: [[B2:%.*]] = mul i32 [[B:%.*]], [[B]]87; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[A:%.*]], [[B2]]88; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 1089; CHECK-NEXT: ret i1 [[CMP]]90;91 %b2 = mul i32 %b, %b ; thwart complexity-based canonicalization92 %c = xor i32 %a, 1093 %cmp = icmp eq i32 %b2, %c94 ret i1 %cmp95}96 97define <2 x i1> @cmpeq_xor_cst1_vec(<2 x i32> %a, <2 x i32> %b) {98; CHECK-LABEL: @cmpeq_xor_cst1_vec(99; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i32> [[A:%.*]], [[B:%.*]]100; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 10, i32 11>101; CHECK-NEXT: ret <2 x i1> [[CMP]]102;103 %c = xor <2 x i32> %a, <i32 10, i32 11>104 %cmp = icmp eq <2 x i32> %b, %c105 ret <2 x i1> %cmp106}107 108; tests from PR65968109define i1 @foo1(i32 %x, i32 %y) {110; CHECK-LABEL: @foo1(111; CHECK-NEXT: [[NEG1:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]112; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[NEG1]], 0113; CHECK-NEXT: ret i1 [[CMP]]114;115 %and = and i32 %x, -2147483648116 %neg = xor i32 %y, -1117 %and1 = and i32 %neg, -2147483648118 %cmp = icmp eq i32 %and, %and1119 ret i1 %cmp120}121 122define i1 @foo2(i32 %x, i32 %y) {123; CHECK-LABEL: @foo2(124; CHECK-NEXT: [[NEG1:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]125; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[NEG1]], 0126; CHECK-NEXT: ret i1 [[CMP]]127;128 %and = and i32 %x, -2147483648129 %neg = and i32 %y, -2147483648130 %and1 = xor i32 %neg, -2147483648131 %cmp = icmp eq i32 %and, %and1132 ret i1 %cmp133}134 135; tests from PR67783136define <2 x i1> @foo3(<2 x i8> %x) {137; CHECK-LABEL: @foo3(138; CHECK-NEXT: entry:139; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i8> [[X:%.*]], <i8 -9, i8 -80>140; CHECK-NEXT: ret <2 x i1> [[CMP]]141;142entry:143 %xor = xor <2 x i8> %x, <i8 -2, i8 -1>144 %cmp = icmp ne <2 x i8> %xor, <i8 9, i8 79>145 ret <2 x i1> %cmp146}147 148declare void @use.i8(i8)149define i1 @fold_xorC_eq0_multiuse(i8 %x, i8 %y) {150; CHECK-LABEL: @fold_xorC_eq0_multiuse(151; CHECK-NEXT: [[XX:%.*]] = xor i8 [[X:%.*]], [[Y:%.*]]152; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[X]], [[Y]]153; CHECK-NEXT: call void @use.i8(i8 [[XX]])154; CHECK-NEXT: ret i1 [[R]]155;156 %xx = xor i8 %x, %y157 %r = icmp eq i8 %xx, 0158 call void @use.i8(i8 %xx)159 ret i1 %r160}161 162define i1 @fold_xorC_eq1_multiuse_fail(i8 %x, i8 %y) {163; CHECK-LABEL: @fold_xorC_eq1_multiuse_fail(164; CHECK-NEXT: [[XX:%.*]] = xor i8 [[X:%.*]], [[Y:%.*]]165; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[XX]], 1166; CHECK-NEXT: call void @use.i8(i8 [[XX]])167; CHECK-NEXT: ret i1 [[R]]168;169 %xx = xor i8 %x, %y170 %r = icmp eq i8 %xx, 1171 call void @use.i8(i8 %xx)172 ret i1 %r173}174 175define i1 @fold_xorC_neC_multiuse(i8 %x) {176; CHECK-LABEL: @fold_xorC_neC_multiuse(177; CHECK-NEXT: [[XX:%.*]] = xor i8 [[X:%.*]], 45178; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[X]], 110179; CHECK-NEXT: call void @use.i8(i8 [[XX]])180; CHECK-NEXT: ret i1 [[R]]181;182 %xx = xor i8 %x, 45183 %r = icmp ne i8 %xx, 67184 call void @use.i8(i8 %xx)185 ret i1 %r186}187