167 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4; 'Negate' is considered less complex than a normal binop, so the xor should have the binop as the first operand.5 6define i8 @neg(i8 %x) {7; CHECK-LABEL: @neg(8; CHECK-NEXT: [[BO:%.*]] = udiv i8 [[X:%.*]], 429; CHECK-NEXT: [[NEGX:%.*]] = sub i8 0, [[X]]10; CHECK-NEXT: [[R:%.*]] = xor i8 [[BO]], [[NEGX]]11; CHECK-NEXT: ret i8 [[R]]12;13 %bo = udiv i8 %x, 4214 %negx = sub i8 0, %x15 %r = xor i8 %negx, %bo16 ret i8 %r17}18 19define <2 x i8> @neg_vec(<2 x i8> %x) {20; CHECK-LABEL: @neg_vec(21; CHECK-NEXT: [[BO:%.*]] = udiv <2 x i8> [[X:%.*]], <i8 42, i8 -42>22; CHECK-NEXT: [[NEGX:%.*]] = sub <2 x i8> zeroinitializer, [[X]]23; CHECK-NEXT: [[R:%.*]] = xor <2 x i8> [[BO]], [[NEGX]]24; CHECK-NEXT: ret <2 x i8> [[R]]25;26 %bo = udiv <2 x i8> %x, <i8 42, i8 -42>27 %negx = sub <2 x i8> <i8 0, i8 0>, %x28 %r = xor <2 x i8> %negx, %bo29 ret <2 x i8> %r30}31 32define <2 x i8> @neg_vec_poison(<2 x i8> %x) {33; CHECK-LABEL: @neg_vec_poison(34; CHECK-NEXT: [[BO:%.*]] = udiv <2 x i8> [[X:%.*]], <i8 42, i8 -42>35; CHECK-NEXT: [[NEGX:%.*]] = sub <2 x i8> <i8 0, i8 poison>, [[X]]36; CHECK-NEXT: [[R:%.*]] = xor <2 x i8> [[BO]], [[NEGX]]37; CHECK-NEXT: ret <2 x i8> [[R]]38;39 %bo = udiv <2 x i8> %x, <i8 42, i8 -42>40 %negx = sub <2 x i8> <i8 0, i8 poison>, %x41 %r = xor <2 x i8> %negx, %bo42 ret <2 x i8> %r43}44 45; 'Not' is considered less complex than a normal binop, so the mul should have the binop as the first operand.46 47define i8 @not(i8 %x) {48; CHECK-LABEL: @not(49; CHECK-NEXT: [[BO:%.*]] = udiv i8 [[X:%.*]], 4250; CHECK-NEXT: [[NOTX:%.*]] = xor i8 [[X]], -151; CHECK-NEXT: [[R:%.*]] = mul i8 [[BO]], [[NOTX]]52; CHECK-NEXT: ret i8 [[R]]53;54 %bo = udiv i8 %x, 4255 %notx = xor i8 -1, %x56 %r = mul i8 %notx, %bo57 ret i8 %r58}59 60define <2 x i8> @not_vec(<2 x i8> %x) {61; CHECK-LABEL: @not_vec(62; CHECK-NEXT: [[BO:%.*]] = udiv <2 x i8> [[X:%.*]], <i8 42, i8 -42>63; CHECK-NEXT: [[NOTX:%.*]] = xor <2 x i8> [[X]], splat (i8 -1)64; CHECK-NEXT: [[R:%.*]] = mul <2 x i8> [[BO]], [[NOTX]]65; CHECK-NEXT: ret <2 x i8> [[R]]66;67 %bo = udiv <2 x i8> %x, <i8 42, i8 -42>68 %notx = xor <2 x i8> <i8 -1, i8 -1>, %x69 %r = mul <2 x i8> %notx, %bo70 ret <2 x i8> %r71}72 73define <2 x i8> @not_vec_poison(<2 x i8> %x) {74; CHECK-LABEL: @not_vec_poison(75; CHECK-NEXT: [[BO:%.*]] = udiv <2 x i8> [[X:%.*]], <i8 42, i8 -42>76; CHECK-NEXT: [[NOTX:%.*]] = xor <2 x i8> [[X]], <i8 -1, i8 poison>77; CHECK-NEXT: [[R:%.*]] = mul <2 x i8> [[BO]], [[NOTX]]78; CHECK-NEXT: ret <2 x i8> [[R]]79;80 %bo = udiv <2 x i8> %x, <i8 42, i8 -42>81 %notx = xor <2 x i8> <i8 -1, i8 poison>, %x82 %r = mul <2 x i8> %notx, %bo83 ret <2 x i8> %r84}85 86; 'Fneg' is considered less complex than a normal binop, so the fmul should have the binop as the first operand.87; Extra uses are required to ensure that the fneg is not canonicalized after the fmul.88 89declare void @use(float)90declare void @use_vec(<2 x float>)91 92define float @fneg(float %x) {93; CHECK-LABEL: @fneg(94; CHECK-NEXT: [[BO:%.*]] = fdiv float [[X:%.*]], 4.200000e+0195; CHECK-NEXT: [[FNEGX:%.*]] = fneg float [[X]]96; CHECK-NEXT: [[R:%.*]] = fmul float [[BO]], [[FNEGX]]97; CHECK-NEXT: call void @use(float [[FNEGX]])98; CHECK-NEXT: ret float [[R]]99;100 %bo = fdiv float %x, 42.0101 %fnegx = fsub float -0.0, %x102 %r = fmul float %fnegx, %bo103 call void @use(float %fnegx)104 ret float %r105}106 107define float @unary_fneg(float %x) {108; CHECK-LABEL: @unary_fneg(109; CHECK-NEXT: [[BO:%.*]] = fdiv float [[X:%.*]], 4.200000e+01110; CHECK-NEXT: [[FNEGX:%.*]] = fneg float [[X]]111; CHECK-NEXT: [[R:%.*]] = fmul float [[BO]], [[FNEGX]]112; CHECK-NEXT: call void @use(float [[FNEGX]])113; CHECK-NEXT: ret float [[R]]114;115 %bo = fdiv float %x, 42.0116 %fnegx = fneg float %x117 %r = fmul float %fnegx, %bo118 call void @use(float %fnegx)119 ret float %r120}121 122define <2 x float> @fneg_vec(<2 x float> %x) {123; CHECK-LABEL: @fneg_vec(124; CHECK-NEXT: [[BO:%.*]] = fdiv <2 x float> [[X:%.*]], <float 4.200000e+01, float -4.200000e+01>125; CHECK-NEXT: [[FNEGX:%.*]] = fneg <2 x float> [[X]]126; CHECK-NEXT: [[R:%.*]] = fmul <2 x float> [[BO]], [[FNEGX]]127; CHECK-NEXT: call void @use_vec(<2 x float> [[FNEGX]])128; CHECK-NEXT: ret <2 x float> [[R]]129;130 %bo = fdiv <2 x float> %x, <float 42.0, float -42.0>131 %fnegx = fsub <2 x float> <float -0.0, float -0.0>, %x132 %r = fmul <2 x float> %fnegx, %bo133 call void @use_vec(<2 x float> %fnegx)134 ret <2 x float> %r135}136 137define <2 x float> @fneg_vec_poison(<2 x float> %x) {138; CHECK-LABEL: @fneg_vec_poison(139; CHECK-NEXT: [[BO:%.*]] = fdiv <2 x float> [[X:%.*]], <float 4.200000e+01, float -4.200000e+01>140; CHECK-NEXT: [[FNEGX:%.*]] = fneg <2 x float> [[X]]141; CHECK-NEXT: [[R:%.*]] = fmul <2 x float> [[BO]], [[FNEGX]]142; CHECK-NEXT: call void @use_vec(<2 x float> [[FNEGX]])143; CHECK-NEXT: ret <2 x float> [[R]]144;145 %bo = fdiv <2 x float> %x, <float 42.0, float -42.0>146 %fnegx = fsub <2 x float> <float -0.0, float poison>, %x147 %r = fmul <2 x float> %fnegx, %bo148 call void @use_vec(<2 x float> %fnegx)149 ret <2 x float> %r150}151 152define <2 x float> @unary_fneg_vec(<2 x float> %x) {153; CHECK-LABEL: @unary_fneg_vec(154; CHECK-NEXT: [[BO:%.*]] = fdiv <2 x float> [[X:%.*]], <float 4.200000e+01, float -4.200000e+01>155; CHECK-NEXT: [[FNEGX:%.*]] = fneg <2 x float> [[X]]156; CHECK-NEXT: [[R:%.*]] = fmul <2 x float> [[BO]], [[FNEGX]]157; CHECK-NEXT: call void @use_vec(<2 x float> [[FNEGX]])158; CHECK-NEXT: ret <2 x float> [[R]]159;160 %bo = fdiv <2 x float> %x, <float 42.0, float -42.0>161 %fnegx = fneg <2 x float> %x162 %r = fmul <2 x float> %fnegx, %bo163 call void @use_vec(<2 x float> %fnegx)164 ret <2 x float> %r165}166 167