581 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.1 | FileCheck %s --check-prefix=CHECK --check-prefix=SSE3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefix=CHECK --check-prefix=AVX --check-prefix=AVX14; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefix=CHECK --check-prefix=AVX --check-prefix=AVX25 6; fold (srem x, 1) -> 07define i32 @combine_srem_by_one(i32 %x) {8; CHECK-LABEL: combine_srem_by_one:9; CHECK: # %bb.0:10; CHECK-NEXT: xorl %eax, %eax11; CHECK-NEXT: retq12 %1 = srem i32 %x, 113 ret i32 %114}15 16define <4 x i32> @combine_vec_srem_by_one(<4 x i32> %x) {17; SSE-LABEL: combine_vec_srem_by_one:18; SSE: # %bb.0:19; SSE-NEXT: xorps %xmm0, %xmm020; SSE-NEXT: retq21;22; AVX-LABEL: combine_vec_srem_by_one:23; AVX: # %bb.0:24; AVX-NEXT: vxorps %xmm0, %xmm0, %xmm025; AVX-NEXT: retq26 %1 = srem <4 x i32> %x, <i32 1, i32 1, i32 1, i32 1>27 ret <4 x i32> %128}29 30; fold (srem x, -1) -> 031define i32 @combine_srem_by_negone(i32 %x) {32; CHECK-LABEL: combine_srem_by_negone:33; CHECK: # %bb.0:34; CHECK-NEXT: xorl %eax, %eax35; CHECK-NEXT: retq36 %1 = srem i32 %x, -137 ret i32 %138}39 40define <4 x i32> @combine_vec_srem_by_negone(<4 x i32> %x) {41; SSE-LABEL: combine_vec_srem_by_negone:42; SSE: # %bb.0:43; SSE-NEXT: xorps %xmm0, %xmm044; SSE-NEXT: retq45;46; AVX-LABEL: combine_vec_srem_by_negone:47; AVX: # %bb.0:48; AVX-NEXT: vxorps %xmm0, %xmm0, %xmm049; AVX-NEXT: retq50 %1 = srem <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1>51 ret <4 x i32> %152}53 54; TODO fold (srem x, INT_MIN)55define i32 @combine_srem_by_minsigned(i32 %x) {56; CHECK-LABEL: combine_srem_by_minsigned:57; CHECK: # %bb.0:58; CHECK-NEXT: # kill: def $edi killed $edi def $rdi59; CHECK-NEXT: leal 2147483647(%rdi), %eax60; CHECK-NEXT: testl %edi, %edi61; CHECK-NEXT: cmovnsl %edi, %eax62; CHECK-NEXT: andl $-2147483648, %eax # imm = 0x8000000063; CHECK-NEXT: addl %edi, %eax64; CHECK-NEXT: retq65 %1 = srem i32 %x, -214748364866 ret i32 %167}68 69define <4 x i32> @combine_vec_srem_by_minsigned(<4 x i32> %x) {70; SSE-LABEL: combine_vec_srem_by_minsigned:71; SSE: # %bb.0:72; SSE-NEXT: movdqa %xmm0, %xmm173; SSE-NEXT: psrad $31, %xmm174; SSE-NEXT: psrld $1, %xmm175; SSE-NEXT: paddd %xmm0, %xmm176; SSE-NEXT: pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm177; SSE-NEXT: paddd %xmm1, %xmm078; SSE-NEXT: retq79;80; AVX1-LABEL: combine_vec_srem_by_minsigned:81; AVX1: # %bb.0:82; AVX1-NEXT: vpsrad $31, %xmm0, %xmm183; AVX1-NEXT: vpsrld $1, %xmm1, %xmm184; AVX1-NEXT: vpaddd %xmm1, %xmm0, %xmm185; AVX1-NEXT: vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm186; AVX1-NEXT: vpaddd %xmm1, %xmm0, %xmm087; AVX1-NEXT: retq88;89; AVX2-LABEL: combine_vec_srem_by_minsigned:90; AVX2: # %bb.0:91; AVX2-NEXT: vpsrad $31, %xmm0, %xmm192; AVX2-NEXT: vpsrld $1, %xmm1, %xmm193; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm194; AVX2-NEXT: vpbroadcastd {{.*#+}} xmm2 = [2147483648,2147483648,2147483648,2147483648]95; AVX2-NEXT: vpand %xmm2, %xmm1, %xmm196; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm097; AVX2-NEXT: retq98 %1 = srem <4 x i32> %x, <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648>99 ret <4 x i32> %1100}101 102; fold (srem 0, x) -> 0103define i32 @combine_srem_zero(i32 %x) {104; CHECK-LABEL: combine_srem_zero:105; CHECK: # %bb.0:106; CHECK-NEXT: xorl %eax, %eax107; CHECK-NEXT: retq108 %1 = srem i32 0, %x109 ret i32 %1110}111 112define <4 x i32> @combine_vec_srem_zero(<4 x i32> %x) {113; SSE-LABEL: combine_vec_srem_zero:114; SSE: # %bb.0:115; SSE-NEXT: xorps %xmm0, %xmm0116; SSE-NEXT: retq117;118; AVX-LABEL: combine_vec_srem_zero:119; AVX: # %bb.0:120; AVX-NEXT: vxorps %xmm0, %xmm0, %xmm0121; AVX-NEXT: retq122 %1 = srem <4 x i32> zeroinitializer, %x123 ret <4 x i32> %1124}125 126; fold (srem x, x) -> 0127define i32 @combine_srem_dupe(i32 %x) {128; CHECK-LABEL: combine_srem_dupe:129; CHECK: # %bb.0:130; CHECK-NEXT: xorl %eax, %eax131; CHECK-NEXT: retq132 %1 = srem i32 %x, %x133 ret i32 %1134}135 136define <4 x i32> @combine_vec_srem_dupe(<4 x i32> %x) {137; SSE-LABEL: combine_vec_srem_dupe:138; SSE: # %bb.0:139; SSE-NEXT: xorps %xmm0, %xmm0140; SSE-NEXT: retq141;142; AVX-LABEL: combine_vec_srem_dupe:143; AVX: # %bb.0:144; AVX-NEXT: vxorps %xmm0, %xmm0, %xmm0145; AVX-NEXT: retq146 %1 = srem <4 x i32> %x, %x147 ret <4 x i32> %1148}149 150; fold (srem x, y) -> (urem x, y) iff x and y are positive151define <4 x i32> @combine_vec_srem_by_pos0(<4 x i32> %x) {152; SSE-LABEL: combine_vec_srem_by_pos0:153; SSE: # %bb.0:154; SSE-NEXT: andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0155; SSE-NEXT: retq156;157; AVX1-LABEL: combine_vec_srem_by_pos0:158; AVX1: # %bb.0:159; AVX1-NEXT: vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0160; AVX1-NEXT: retq161;162; AVX2-LABEL: combine_vec_srem_by_pos0:163; AVX2: # %bb.0:164; AVX2-NEXT: vbroadcastss {{.*#+}} xmm1 = [3,3,3,3]165; AVX2-NEXT: vandps %xmm1, %xmm0, %xmm0166; AVX2-NEXT: retq167 %1 = and <4 x i32> %x, <i32 255, i32 255, i32 255, i32 255>168 %2 = srem <4 x i32> %1, <i32 4, i32 4, i32 4, i32 4>169 ret <4 x i32> %2170}171 172define <4 x i32> @combine_vec_srem_by_pos1(<4 x i32> %x) {173; SSE-LABEL: combine_vec_srem_by_pos1:174; SSE: # %bb.0:175; SSE-NEXT: andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0176; SSE-NEXT: retq177;178; AVX-LABEL: combine_vec_srem_by_pos1:179; AVX: # %bb.0:180; AVX-NEXT: vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0181; AVX-NEXT: retq182 %1 = and <4 x i32> %x, <i32 255, i32 255, i32 255, i32 255>183 %2 = srem <4 x i32> %1, <i32 1, i32 4, i32 8, i32 16>184 ret <4 x i32> %2185}186 187; fold (srem x, (1 << c)) -> x - (x / (1 << c)) * (1 << c).188define <4 x i32> @combine_vec_srem_by_pow2a(<4 x i32> %x) {189; SSE-LABEL: combine_vec_srem_by_pow2a:190; SSE: # %bb.0:191; SSE-NEXT: movdqa %xmm0, %xmm1192; SSE-NEXT: psrad $31, %xmm1193; SSE-NEXT: psrld $30, %xmm1194; SSE-NEXT: paddd %xmm0, %xmm1195; SSE-NEXT: pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1196; SSE-NEXT: psubd %xmm1, %xmm0197; SSE-NEXT: retq198;199; AVX1-LABEL: combine_vec_srem_by_pow2a:200; AVX1: # %bb.0:201; AVX1-NEXT: vpsrad $31, %xmm0, %xmm1202; AVX1-NEXT: vpsrld $30, %xmm1, %xmm1203; AVX1-NEXT: vpaddd %xmm1, %xmm0, %xmm1204; AVX1-NEXT: vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm1205; AVX1-NEXT: vpsubd %xmm1, %xmm0, %xmm0206; AVX1-NEXT: retq207;208; AVX2-LABEL: combine_vec_srem_by_pow2a:209; AVX2: # %bb.0:210; AVX2-NEXT: vpsrad $31, %xmm0, %xmm1211; AVX2-NEXT: vpsrld $30, %xmm1, %xmm1212; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm1213; AVX2-NEXT: vpbroadcastd {{.*#+}} xmm2 = [4294967292,4294967292,4294967292,4294967292]214; AVX2-NEXT: vpand %xmm2, %xmm1, %xmm1215; AVX2-NEXT: vpsubd %xmm1, %xmm0, %xmm0216; AVX2-NEXT: retq217 %1 = srem <4 x i32> %x, <i32 4, i32 4, i32 4, i32 4>218 ret <4 x i32> %1219}220 221define <4 x i32> @combine_vec_srem_by_pow2a_neg(<4 x i32> %x) {222; SSE-LABEL: combine_vec_srem_by_pow2a_neg:223; SSE: # %bb.0:224; SSE-NEXT: movdqa %xmm0, %xmm1225; SSE-NEXT: psrad $31, %xmm1226; SSE-NEXT: psrld $30, %xmm1227; SSE-NEXT: paddd %xmm0, %xmm1228; SSE-NEXT: pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1229; SSE-NEXT: psubd %xmm1, %xmm0230; SSE-NEXT: retq231;232; AVX1-LABEL: combine_vec_srem_by_pow2a_neg:233; AVX1: # %bb.0:234; AVX1-NEXT: vpsrad $31, %xmm0, %xmm1235; AVX1-NEXT: vpsrld $30, %xmm1, %xmm1236; AVX1-NEXT: vpaddd %xmm1, %xmm0, %xmm1237; AVX1-NEXT: vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm1238; AVX1-NEXT: vpsubd %xmm1, %xmm0, %xmm0239; AVX1-NEXT: retq240;241; AVX2-LABEL: combine_vec_srem_by_pow2a_neg:242; AVX2: # %bb.0:243; AVX2-NEXT: vpsrad $31, %xmm0, %xmm1244; AVX2-NEXT: vpsrld $30, %xmm1, %xmm1245; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm1246; AVX2-NEXT: vpbroadcastd {{.*#+}} xmm2 = [4294967292,4294967292,4294967292,4294967292]247; AVX2-NEXT: vpand %xmm2, %xmm1, %xmm1248; AVX2-NEXT: vpsubd %xmm1, %xmm0, %xmm0249; AVX2-NEXT: retq250 %1 = srem <4 x i32> %x, <i32 -4, i32 -4, i32 -4, i32 -4>251 ret <4 x i32> %1252}253 254define <4 x i32> @combine_vec_srem_by_pow2b(<4 x i32> %x) {255; SSE-LABEL: combine_vec_srem_by_pow2b:256; SSE: # %bb.0:257; SSE-NEXT: movdqa %xmm0, %xmm1258; SSE-NEXT: psrld $31, %xmm1259; SSE-NEXT: movdqa %xmm0, %xmm2260; SSE-NEXT: psrad $31, %xmm2261; SSE-NEXT: movdqa %xmm2, %xmm3262; SSE-NEXT: psrld $29, %xmm3263; SSE-NEXT: pblendw {{.*#+}} xmm3 = xmm1[0,1,2,3],xmm3[4,5,6,7]264; SSE-NEXT: psrld $30, %xmm2265; SSE-NEXT: pblendw {{.*#+}} xmm2 = xmm2[0,1],xmm3[2,3],xmm2[4,5],xmm3[6,7]266; SSE-NEXT: paddd %xmm0, %xmm2267; SSE-NEXT: movdqa %xmm2, %xmm1268; SSE-NEXT: psrad $3, %xmm1269; SSE-NEXT: movdqa %xmm2, %xmm3270; SSE-NEXT: psrad $1, %xmm3271; SSE-NEXT: pblendw {{.*#+}} xmm3 = xmm3[0,1,2,3],xmm1[4,5,6,7]272; SSE-NEXT: psrad $2, %xmm2273; SSE-NEXT: pblendw {{.*#+}} xmm2 = xmm2[0,1],xmm3[2,3],xmm2[4,5],xmm3[6,7]274; SSE-NEXT: pblendw {{.*#+}} xmm2 = xmm0[0,1],xmm2[2,3,4,5,6,7]275; SSE-NEXT: pmulld {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm2 # [1,2,4,8]276; SSE-NEXT: psubd %xmm2, %xmm0277; SSE-NEXT: retq278;279; AVX1-LABEL: combine_vec_srem_by_pow2b:280; AVX1: # %bb.0:281; AVX1-NEXT: vpsrld $31, %xmm0, %xmm1282; AVX1-NEXT: vpsrad $31, %xmm0, %xmm2283; AVX1-NEXT: vpsrld $29, %xmm2, %xmm3284; AVX1-NEXT: vpblendw {{.*#+}} xmm1 = xmm1[0,1,2,3],xmm3[4,5,6,7]285; AVX1-NEXT: vpsrld $30, %xmm2, %xmm2286; AVX1-NEXT: vpblendw {{.*#+}} xmm1 = xmm2[0,1],xmm1[2,3],xmm2[4,5],xmm1[6,7]287; AVX1-NEXT: vpaddd %xmm1, %xmm0, %xmm1288; AVX1-NEXT: vpsrad $3, %xmm1, %xmm2289; AVX1-NEXT: vpsrad $1, %xmm1, %xmm3290; AVX1-NEXT: vpblendw {{.*#+}} xmm2 = xmm3[0,1,2,3],xmm2[4,5,6,7]291; AVX1-NEXT: vpsrad $2, %xmm1, %xmm1292; AVX1-NEXT: vpblendw {{.*#+}} xmm1 = xmm1[0,1],xmm2[2,3],xmm1[4,5],xmm2[6,7]293; AVX1-NEXT: vpblendw {{.*#+}} xmm1 = xmm0[0,1],xmm1[2,3,4,5,6,7]294; AVX1-NEXT: vpmulld {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm1 # [1,2,4,8]295; AVX1-NEXT: vpsubd %xmm1, %xmm0, %xmm0296; AVX1-NEXT: retq297;298; AVX2-LABEL: combine_vec_srem_by_pow2b:299; AVX2: # %bb.0:300; AVX2-NEXT: vpsrad $31, %xmm0, %xmm1301; AVX2-NEXT: vpsrlvd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm1302; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm1303; AVX2-NEXT: vpmovsxbd {{.*#+}} xmm2 = [0,1,2,3]304; AVX2-NEXT: vpsravd %xmm2, %xmm1, %xmm1305; AVX2-NEXT: vpblendd {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3]306; AVX2-NEXT: vpsllvd %xmm2, %xmm1, %xmm1307; AVX2-NEXT: vpsubd %xmm1, %xmm0, %xmm0308; AVX2-NEXT: retq309 %1 = srem <4 x i32> %x, <i32 1, i32 2, i32 4, i32 8>310 ret <4 x i32> %1311}312 313define <4 x i32> @combine_vec_srem_by_pow2b_neg(<4 x i32> %x) {314; SSE-LABEL: combine_vec_srem_by_pow2b_neg:315; SSE: # %bb.0:316; SSE-NEXT: movdqa %xmm0, %xmm1317; SSE-NEXT: psrad $31, %xmm1318; SSE-NEXT: movdqa %xmm1, %xmm2319; SSE-NEXT: psrld $28, %xmm2320; SSE-NEXT: movdqa %xmm1, %xmm3321; SSE-NEXT: psrld $30, %xmm3322; SSE-NEXT: pblendw {{.*#+}} xmm3 = xmm3[0,1,2,3],xmm2[4,5,6,7]323; SSE-NEXT: movdqa %xmm0, %xmm2324; SSE-NEXT: psrld $31, %xmm2325; SSE-NEXT: psrld $29, %xmm1326; SSE-NEXT: pblendw {{.*#+}} xmm1 = xmm2[0,1,2,3],xmm1[4,5,6,7]327; SSE-NEXT: pblendw {{.*#+}} xmm1 = xmm1[0,1],xmm3[2,3],xmm1[4,5],xmm3[6,7]328; SSE-NEXT: paddd %xmm0, %xmm1329; SSE-NEXT: movdqa %xmm1, %xmm2330; SSE-NEXT: psrad $4, %xmm2331; SSE-NEXT: movdqa %xmm1, %xmm3332; SSE-NEXT: psrad $2, %xmm3333; SSE-NEXT: pblendw {{.*#+}} xmm3 = xmm3[0,1,2,3],xmm2[4,5,6,7]334; SSE-NEXT: movdqa %xmm1, %xmm2335; SSE-NEXT: psrad $3, %xmm2336; SSE-NEXT: psrld $1, %xmm1337; SSE-NEXT: pblendw {{.*#+}} xmm1 = xmm1[0,1,2,3],xmm2[4,5,6,7]338; SSE-NEXT: pblendw {{.*#+}} xmm1 = xmm1[0,1],xmm3[2,3],xmm1[4,5],xmm3[6,7]339; SSE-NEXT: pmulld {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1 # [4294967294,4294967292,4294967288,4294967280]340; SSE-NEXT: paddd %xmm1, %xmm0341; SSE-NEXT: retq342;343; AVX1-LABEL: combine_vec_srem_by_pow2b_neg:344; AVX1: # %bb.0:345; AVX1-NEXT: vpsrad $31, %xmm0, %xmm1346; AVX1-NEXT: vpsrld $28, %xmm1, %xmm2347; AVX1-NEXT: vpsrld $30, %xmm1, %xmm3348; AVX1-NEXT: vpblendw {{.*#+}} xmm2 = xmm3[0,1,2,3],xmm2[4,5,6,7]349; AVX1-NEXT: vpsrld $31, %xmm0, %xmm3350; AVX1-NEXT: vpsrld $29, %xmm1, %xmm1351; AVX1-NEXT: vpblendw {{.*#+}} xmm1 = xmm3[0,1,2,3],xmm1[4,5,6,7]352; AVX1-NEXT: vpblendw {{.*#+}} xmm1 = xmm1[0,1],xmm2[2,3],xmm1[4,5],xmm2[6,7]353; AVX1-NEXT: vpaddd %xmm1, %xmm0, %xmm1354; AVX1-NEXT: vpsrad $4, %xmm1, %xmm2355; AVX1-NEXT: vpsrad $2, %xmm1, %xmm3356; AVX1-NEXT: vpblendw {{.*#+}} xmm2 = xmm3[0,1,2,3],xmm2[4,5,6,7]357; AVX1-NEXT: vpsrad $3, %xmm1, %xmm3358; AVX1-NEXT: vpsrld $1, %xmm1, %xmm1359; AVX1-NEXT: vpblendw {{.*#+}} xmm1 = xmm1[0,1,2,3],xmm3[4,5,6,7]360; AVX1-NEXT: vpblendw {{.*#+}} xmm1 = xmm1[0,1],xmm2[2,3],xmm1[4,5],xmm2[6,7]361; AVX1-NEXT: vpmulld {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm1 # [4294967294,4294967292,4294967288,4294967280]362; AVX1-NEXT: vpaddd %xmm1, %xmm0, %xmm0363; AVX1-NEXT: retq364;365; AVX2-LABEL: combine_vec_srem_by_pow2b_neg:366; AVX2: # %bb.0:367; AVX2-NEXT: vpsrad $31, %xmm0, %xmm1368; AVX2-NEXT: vpsrlvd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm1369; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm1370; AVX2-NEXT: vpsravd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm1371; AVX2-NEXT: vpmulld {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm1 # [4294967294,4294967292,4294967288,4294967280]372; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm0373; AVX2-NEXT: retq374 %1 = srem <4 x i32> %x, <i32 -2, i32 -4, i32 -8, i32 -16>375 ret <4 x i32> %1376}377 378; FIXME: PR55271 - srem(undef, 3) != undef379; Use PSLLI intrinsic to postpone the undef creation until after urem-by-constant expansion380define <4 x i32> @combine_vec_srem_undef_by_3(<4 x i32> %in) {381; CHECK-LABEL: combine_vec_srem_undef_by_3:382; CHECK: # %bb.0:383; CHECK-NEXT: retq384 %x = call <4 x i32> @llvm.x86.sse2.pslli.d(<4 x i32> undef, i32 0)385 %y = srem <4 x i32> %x, <i32 3, i32 3, i32 3, i32 3>386 ret <4 x i32> %y387}388declare <4 x i32> @llvm.x86.sse2.pslli.d(<4 x i32>, i32)389 390; OSS-Fuzz #6883391; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=6883392define i32 @ossfuzz6883() {393; CHECK-LABEL: ossfuzz6883:394; CHECK: # %bb.0:395; CHECK-NEXT: movl (%rax), %ecx396; CHECK-NEXT: movl $2147483647, %eax # imm = 0x7FFFFFFF397; CHECK-NEXT: xorl %edx, %edx398; CHECK-NEXT: idivl %ecx399; CHECK-NEXT: movl %eax, %esi400; CHECK-NEXT: movl $2147483647, %eax # imm = 0x7FFFFFFF401; CHECK-NEXT: xorl %edx, %edx402; CHECK-NEXT: divl %ecx403; CHECK-NEXT: movl %eax, %edi404; CHECK-NEXT: movl %esi, %eax405; CHECK-NEXT: cltd406; CHECK-NEXT: idivl %edi407; CHECK-NEXT: movl %edx, %esi408; CHECK-NEXT: movl %ecx, %eax409; CHECK-NEXT: cltd410; CHECK-NEXT: idivl %esi411; CHECK-NEXT: movl %edx, %edi412; CHECK-NEXT: movl %ecx, %eax413; CHECK-NEXT: xorl %edx, %edx414; CHECK-NEXT: divl %esi415; CHECK-NEXT: andl %edi, %eax416; CHECK-NEXT: retq417 %B17 = or i32 0, 2147483647418 %L6 = load i32, ptr undef419 %B11 = sdiv i32 %B17, %L6420 %B13 = udiv i32 %B17, %L6421 %B14 = srem i32 %B11, %B13422 %B16 = srem i32 %L6, %B14423 %B10 = udiv i32 %L6, %B14424 %B6 = and i32 %B16, %B10425 ret i32 %B6426}427 428define i1 @bool_srem(i1 %x, i1 %y) {429; CHECK-LABEL: bool_srem:430; CHECK: # %bb.0:431; CHECK-NEXT: xorl %eax, %eax432; CHECK-NEXT: retq433 %r = srem i1 %x, %y434 ret i1 %r435}436define <4 x i1> @boolvec_srem(<4 x i1> %x, <4 x i1> %y) {437; SSE-LABEL: boolvec_srem:438; SSE: # %bb.0:439; SSE-NEXT: xorps %xmm0, %xmm0440; SSE-NEXT: retq441;442; AVX-LABEL: boolvec_srem:443; AVX: # %bb.0:444; AVX-NEXT: vxorps %xmm0, %xmm0, %xmm0445; AVX-NEXT: retq446 %r = srem <4 x i1> %x, %y447 ret <4 x i1> %r448}449 450define i32 @combine_srem_two(i32 %x) {451; CHECK-LABEL: combine_srem_two:452; CHECK: # %bb.0:453; CHECK-NEXT: movl %edi, %eax454; CHECK-NEXT: movl %edi, %ecx455; CHECK-NEXT: shrl $31, %ecx456; CHECK-NEXT: addl %edi, %ecx457; CHECK-NEXT: andl $-2, %ecx458; CHECK-NEXT: subl %ecx, %eax459; CHECK-NEXT: retq460 %1 = srem i32 %x, 2461 ret i32 %1462}463 464define i32 @combine_srem_negtwo(i32 %x) {465; CHECK-LABEL: combine_srem_negtwo:466; CHECK: # %bb.0:467; CHECK-NEXT: movl %edi, %eax468; CHECK-NEXT: movl %edi, %ecx469; CHECK-NEXT: shrl $31, %ecx470; CHECK-NEXT: addl %edi, %ecx471; CHECK-NEXT: andl $-2, %ecx472; CHECK-NEXT: subl %ecx, %eax473; CHECK-NEXT: retq474 %1 = srem i32 %x, -2475 ret i32 %1476}477 478define i8 @combine_i8_srem_negpow2(i8 %x) {479; CHECK-LABEL: combine_i8_srem_negpow2:480; CHECK: # %bb.0:481; CHECK-NEXT: movl %edi, %eax482; CHECK-NEXT: movl %eax, %ecx483; CHECK-NEXT: sarb $7, %cl484; CHECK-NEXT: shrb $2, %cl485; CHECK-NEXT: addb %al, %cl486; CHECK-NEXT: andb $-64, %cl487; CHECK-NEXT: subb %cl, %al488; CHECK-NEXT: # kill: def $al killed $al killed $eax489; CHECK-NEXT: retq490 %1 = srem i8 %x, -64491 ret i8 %1492}493 494define i16 @combine_i16_srem_pow2(i16 %x) {495; CHECK-LABEL: combine_i16_srem_pow2:496; CHECK: # %bb.0:497; CHECK-NEXT: movl %edi, %eax498; CHECK-NEXT: leal 15(%rax), %ecx499; CHECK-NEXT: testw %ax, %ax500; CHECK-NEXT: cmovnsl %edi, %ecx501; CHECK-NEXT: andl $-16, %ecx502; CHECK-NEXT: subl %ecx, %eax503; CHECK-NEXT: # kill: def $ax killed $ax killed $rax504; CHECK-NEXT: retq505 %1 = srem i16 %x, 16506 ret i16 %1507}508 509define i16 @combine_i16_srem_negpow2(i16 %x) {510; CHECK-LABEL: combine_i16_srem_negpow2:511; CHECK: # %bb.0:512; CHECK-NEXT: movl %edi, %eax513; CHECK-NEXT: leal 255(%rax), %ecx514; CHECK-NEXT: testw %ax, %ax515; CHECK-NEXT: cmovnsl %edi, %ecx516; CHECK-NEXT: andl $-256, %ecx517; CHECK-NEXT: subl %ecx, %eax518; CHECK-NEXT: # kill: def $ax killed $ax killed $rax519; CHECK-NEXT: retq520 %1 = srem i16 %x, -256521 ret i16 %1522}523 524define i32 @combine_srem_pow2(i32 %x) {525; CHECK-LABEL: combine_srem_pow2:526; CHECK: # %bb.0:527; CHECK-NEXT: movl %edi, %eax528; CHECK-NEXT: leal 15(%rax), %ecx529; CHECK-NEXT: testl %edi, %edi530; CHECK-NEXT: cmovnsl %edi, %ecx531; CHECK-NEXT: andl $-16, %ecx532; CHECK-NEXT: subl %ecx, %eax533; CHECK-NEXT: # kill: def $eax killed $eax killed $rax534; CHECK-NEXT: retq535 %1 = srem i32 %x, 16536 ret i32 %1537}538 539define i32 @combine_srem_negpow2(i32 %x) {540; CHECK-LABEL: combine_srem_negpow2:541; CHECK: # %bb.0:542; CHECK-NEXT: movl %edi, %eax543; CHECK-NEXT: leal 255(%rax), %ecx544; CHECK-NEXT: testl %edi, %edi545; CHECK-NEXT: cmovnsl %edi, %ecx546; CHECK-NEXT: andl $-256, %ecx547; CHECK-NEXT: subl %ecx, %eax548; CHECK-NEXT: # kill: def $eax killed $eax killed $rax549; CHECK-NEXT: retq550 %1 = srem i32 %x, -256551 ret i32 %1552}553 554define i64 @combine_i64_srem_pow2(i64 %x) {555; CHECK-LABEL: combine_i64_srem_pow2:556; CHECK: # %bb.0:557; CHECK-NEXT: movq %rdi, %rax558; CHECK-NEXT: leaq 15(%rdi), %rcx559; CHECK-NEXT: testq %rdi, %rdi560; CHECK-NEXT: cmovnsq %rdi, %rcx561; CHECK-NEXT: andq $-16, %rcx562; CHECK-NEXT: subq %rcx, %rax563; CHECK-NEXT: retq564 %1 = srem i64 %x, 16565 ret i64 %1566}567 568define i64 @combine_i64_srem_negpow2(i64 %x) {569; CHECK-LABEL: combine_i64_srem_negpow2:570; CHECK: # %bb.0:571; CHECK-NEXT: movq %rdi, %rax572; CHECK-NEXT: leaq 255(%rdi), %rcx573; CHECK-NEXT: testq %rdi, %rdi574; CHECK-NEXT: cmovnsq %rdi, %rcx575; CHECK-NEXT: andq $-256, %rcx576; CHECK-NEXT: subq %rcx, %rax577; CHECK-NEXT: retq578 %1 = srem i64 %x, -256579 ret i64 %1580}581