1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.1 | FileCheck %s --check-prefix=CHECK --check-prefix=SSE 3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefix=CHECK --check-prefix=AVX --check-prefix=AVX1 4; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefix=CHECK --check-prefix=AVX --check-prefix=AVX2 5 6; fold (srem x, 1) -> 0 7define i32 @combine_srem_by_one(i32 %x) { 8; CHECK-LABEL: combine_srem_by_one: 9; CHECK: # %bb.0: 10; CHECK-NEXT: xorl %eax, %eax 11; CHECK-NEXT: retq 12 %1 = srem i32 %x, 1 13 ret i32 %1 14} 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, %xmm0 20; SSE-NEXT: retq 21; 22; AVX-LABEL: combine_vec_srem_by_one: 23; AVX: # %bb.0: 24; AVX-NEXT: vxorps %xmm0, %xmm0, %xmm0 25; AVX-NEXT: retq 26 %1 = srem <4 x i32> %x, <i32 1, i32 1, i32 1, i32 1> 27 ret <4 x i32> %1 28} 29 30; fold (srem x, -1) -> 0 31define i32 @combine_srem_by_negone(i32 %x) { 32; CHECK-LABEL: combine_srem_by_negone: 33; CHECK: # %bb.0: 34; CHECK-NEXT: xorl %eax, %eax 35; CHECK-NEXT: retq 36 %1 = srem i32 %x, -1 37 ret i32 %1 38} 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, %xmm0 44; SSE-NEXT: retq 45; 46; AVX-LABEL: combine_vec_srem_by_negone: 47; AVX: # %bb.0: 48; AVX-NEXT: vxorps %xmm0, %xmm0, %xmm0 49; AVX-NEXT: retq 50 %1 = srem <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1> 51 ret <4 x i32> %1 52} 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 $rdi 59; CHECK-NEXT: leal 2147483647(%rdi), %eax 60; CHECK-NEXT: testl %edi, %edi 61; CHECK-NEXT: cmovnsl %edi, %eax 62; CHECK-NEXT: andl $-2147483648, %eax # imm = 0x80000000 63; CHECK-NEXT: addl %edi, %eax 64; CHECK-NEXT: retq 65 %1 = srem i32 %x, -2147483648 66 ret i32 %1 67} 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, %xmm1 73; SSE-NEXT: psrad $31, %xmm1 74; SSE-NEXT: psrld $1, %xmm1 75; SSE-NEXT: paddd %xmm0, %xmm1 76; SSE-NEXT: pand {{.*}}(%rip), %xmm1 77; SSE-NEXT: psubd %xmm1, %xmm0 78; SSE-NEXT: retq 79; 80; AVX1-LABEL: combine_vec_srem_by_minsigned: 81; AVX1: # %bb.0: 82; AVX1-NEXT: vpsrad $31, %xmm0, %xmm1 83; AVX1-NEXT: vpsrld $1, %xmm1, %xmm1 84; AVX1-NEXT: vpaddd %xmm1, %xmm0, %xmm1 85; AVX1-NEXT: vpand {{.*}}(%rip), %xmm1, %xmm1 86; AVX1-NEXT: vpsubd %xmm1, %xmm0, %xmm0 87; AVX1-NEXT: retq 88; 89; AVX2-LABEL: combine_vec_srem_by_minsigned: 90; AVX2: # %bb.0: 91; AVX2-NEXT: vpsrad $31, %xmm0, %xmm1 92; AVX2-NEXT: vpsrld $1, %xmm1, %xmm1 93; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm1 94; AVX2-NEXT: vpbroadcastd {{.*#+}} xmm2 = [2147483648,2147483648,2147483648,2147483648] 95; AVX2-NEXT: vpand %xmm2, %xmm1, %xmm1 96; AVX2-NEXT: vpsubd %xmm1, %xmm0, %xmm0 97; AVX2-NEXT: retq 98 %1 = srem <4 x i32> %x, <i32 -2147483648, i32 -2147483648, i32 -2147483648, i32 -2147483648> 99 ret <4 x i32> %1 100} 101 102; fold (srem 0, x) -> 0 103define i32 @combine_srem_zero(i32 %x) { 104; CHECK-LABEL: combine_srem_zero: 105; CHECK: # %bb.0: 106; CHECK-NEXT: xorl %eax, %eax 107; CHECK-NEXT: retq 108 %1 = srem i32 0, %x 109 ret i32 %1 110} 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, %xmm0 116; SSE-NEXT: retq 117; 118; AVX-LABEL: combine_vec_srem_zero: 119; AVX: # %bb.0: 120; AVX-NEXT: vxorps %xmm0, %xmm0, %xmm0 121; AVX-NEXT: retq 122 %1 = srem <4 x i32> zeroinitializer, %x 123 ret <4 x i32> %1 124} 125 126; fold (srem x, x) -> 0 127define i32 @combine_srem_dupe(i32 %x) { 128; CHECK-LABEL: combine_srem_dupe: 129; CHECK: # %bb.0: 130; CHECK-NEXT: xorl %eax, %eax 131; CHECK-NEXT: retq 132 %1 = srem i32 %x, %x 133 ret i32 %1 134} 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, %xmm0 140; SSE-NEXT: retq 141; 142; AVX-LABEL: combine_vec_srem_dupe: 143; AVX: # %bb.0: 144; AVX-NEXT: vxorps %xmm0, %xmm0, %xmm0 145; AVX-NEXT: retq 146 %1 = srem <4 x i32> %x, %x 147 ret <4 x i32> %1 148} 149 150; fold (srem x, y) -> (urem x, y) iff x and y are positive 151define <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 {{.*}}(%rip), %xmm0 155; SSE-NEXT: retq 156; 157; AVX1-LABEL: combine_vec_srem_by_pos0: 158; AVX1: # %bb.0: 159; AVX1-NEXT: vandps {{.*}}(%rip), %xmm0, %xmm0 160; AVX1-NEXT: retq 161; 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, %xmm0 166; AVX2-NEXT: retq 167 %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> %2 170} 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 {{.*}}(%rip), %xmm0 176; SSE-NEXT: retq 177; 178; AVX-LABEL: combine_vec_srem_by_pos1: 179; AVX: # %bb.0: 180; AVX-NEXT: vandps {{.*}}(%rip), %xmm0, %xmm0 181; AVX-NEXT: retq 182 %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> %2 185} 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, %xmm1 192; SSE-NEXT: psrad $31, %xmm1 193; SSE-NEXT: psrld $30, %xmm1 194; SSE-NEXT: paddd %xmm0, %xmm1 195; SSE-NEXT: pand {{.*}}(%rip), %xmm1 196; SSE-NEXT: psubd %xmm1, %xmm0 197; SSE-NEXT: retq 198; 199; AVX1-LABEL: combine_vec_srem_by_pow2a: 200; AVX1: # %bb.0: 201; AVX1-NEXT: vpsrad $31, %xmm0, %xmm1 202; AVX1-NEXT: vpsrld $30, %xmm1, %xmm1 203; AVX1-NEXT: vpaddd %xmm1, %xmm0, %xmm1 204; AVX1-NEXT: vpand {{.*}}(%rip), %xmm1, %xmm1 205; AVX1-NEXT: vpsubd %xmm1, %xmm0, %xmm0 206; AVX1-NEXT: retq 207; 208; AVX2-LABEL: combine_vec_srem_by_pow2a: 209; AVX2: # %bb.0: 210; AVX2-NEXT: vpsrad $31, %xmm0, %xmm1 211; AVX2-NEXT: vpsrld $30, %xmm1, %xmm1 212; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm1 213; AVX2-NEXT: vpbroadcastd {{.*#+}} xmm2 = [4294967292,4294967292,4294967292,4294967292] 214; AVX2-NEXT: vpand %xmm2, %xmm1, %xmm1 215; AVX2-NEXT: vpsubd %xmm1, %xmm0, %xmm0 216; AVX2-NEXT: retq 217 %1 = srem <4 x i32> %x, <i32 4, i32 4, i32 4, i32 4> 218 ret <4 x i32> %1 219} 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, %xmm1 225; SSE-NEXT: psrad $31, %xmm1 226; SSE-NEXT: psrld $30, %xmm1 227; SSE-NEXT: paddd %xmm0, %xmm1 228; SSE-NEXT: psrld $2, %xmm1 229; SSE-NEXT: pxor %xmm2, %xmm2 230; SSE-NEXT: psubd %xmm1, %xmm2 231; SSE-NEXT: pslld $2, %xmm2 232; SSE-NEXT: paddd %xmm2, %xmm0 233; SSE-NEXT: retq 234; 235; AVX-LABEL: combine_vec_srem_by_pow2a_neg: 236; AVX: # %bb.0: 237; AVX-NEXT: vpsrad $31, %xmm0, %xmm1 238; AVX-NEXT: vpsrld $30, %xmm1, %xmm1 239; AVX-NEXT: vpaddd %xmm1, %xmm0, %xmm1 240; AVX-NEXT: vpsrld $2, %xmm1, %xmm1 241; AVX-NEXT: vpxor %xmm2, %xmm2, %xmm2 242; AVX-NEXT: vpsubd %xmm1, %xmm2, %xmm1 243; AVX-NEXT: vpslld $2, %xmm1, %xmm1 244; AVX-NEXT: vpaddd %xmm1, %xmm0, %xmm0 245; AVX-NEXT: retq 246 %1 = srem <4 x i32> %x, <i32 -4, i32 -4, i32 -4, i32 -4> 247 ret <4 x i32> %1 248} 249 250define <4 x i32> @combine_vec_srem_by_pow2b(<4 x i32> %x) { 251; SSE-LABEL: combine_vec_srem_by_pow2b: 252; SSE: # %bb.0: 253; SSE-NEXT: movdqa %xmm0, %xmm1 254; SSE-NEXT: psrad $31, %xmm1 255; SSE-NEXT: movdqa %xmm1, %xmm2 256; SSE-NEXT: psrld $29, %xmm2 257; SSE-NEXT: movdqa %xmm1, %xmm3 258; SSE-NEXT: psrld $31, %xmm3 259; SSE-NEXT: pblendw {{.*#+}} xmm3 = xmm3[0,1,2,3],xmm2[4,5,6,7] 260; SSE-NEXT: psrld $30, %xmm1 261; SSE-NEXT: pblendw {{.*#+}} xmm1 = xmm1[0,1],xmm3[2,3],xmm1[4,5],xmm3[6,7] 262; SSE-NEXT: paddd %xmm0, %xmm1 263; SSE-NEXT: movdqa %xmm1, %xmm2 264; SSE-NEXT: psrad $3, %xmm2 265; SSE-NEXT: movdqa %xmm1, %xmm3 266; SSE-NEXT: psrad $1, %xmm3 267; SSE-NEXT: pblendw {{.*#+}} xmm3 = xmm3[0,1,2,3],xmm2[4,5,6,7] 268; SSE-NEXT: psrad $2, %xmm1 269; SSE-NEXT: pblendw {{.*#+}} xmm1 = xmm1[0,1],xmm3[2,3],xmm1[4,5],xmm3[6,7] 270; SSE-NEXT: pblendw {{.*#+}} xmm1 = xmm0[0,1],xmm1[2,3,4,5,6,7] 271; SSE-NEXT: pmulld {{.*}}(%rip), %xmm1 272; SSE-NEXT: psubd %xmm1, %xmm0 273; SSE-NEXT: retq 274; 275; AVX1-LABEL: combine_vec_srem_by_pow2b: 276; AVX1: # %bb.0: 277; AVX1-NEXT: vpsrad $31, %xmm0, %xmm1 278; AVX1-NEXT: vpsrld $29, %xmm1, %xmm2 279; AVX1-NEXT: vpsrld $31, %xmm1, %xmm3 280; AVX1-NEXT: vpblendw {{.*#+}} xmm2 = xmm3[0,1,2,3],xmm2[4,5,6,7] 281; AVX1-NEXT: vpsrld $30, %xmm1, %xmm1 282; AVX1-NEXT: vpblendw {{.*#+}} xmm1 = xmm1[0,1],xmm2[2,3],xmm1[4,5],xmm2[6,7] 283; AVX1-NEXT: vpaddd %xmm1, %xmm0, %xmm1 284; AVX1-NEXT: vpsrad $3, %xmm1, %xmm2 285; AVX1-NEXT: vpsrad $1, %xmm1, %xmm3 286; AVX1-NEXT: vpblendw {{.*#+}} xmm2 = xmm3[0,1,2,3],xmm2[4,5,6,7] 287; AVX1-NEXT: vpsrad $2, %xmm1, %xmm1 288; AVX1-NEXT: vpblendw {{.*#+}} xmm1 = xmm1[0,1],xmm2[2,3],xmm1[4,5],xmm2[6,7] 289; AVX1-NEXT: vpblendw {{.*#+}} xmm1 = xmm0[0,1],xmm1[2,3,4,5,6,7] 290; AVX1-NEXT: vpmulld {{.*}}(%rip), %xmm1, %xmm1 291; AVX1-NEXT: vpsubd %xmm1, %xmm0, %xmm0 292; AVX1-NEXT: retq 293; 294; AVX2-LABEL: combine_vec_srem_by_pow2b: 295; AVX2: # %bb.0: 296; AVX2-NEXT: vpsrad $31, %xmm0, %xmm1 297; AVX2-NEXT: vpsrlvd {{.*}}(%rip), %xmm1, %xmm1 298; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm1 299; AVX2-NEXT: vmovdqa {{.*#+}} xmm2 = [0,1,2,3] 300; AVX2-NEXT: vpsravd %xmm2, %xmm1, %xmm1 301; AVX2-NEXT: vpblendd {{.*#+}} xmm1 = xmm0[0],xmm1[1,2,3] 302; AVX2-NEXT: vpsllvd %xmm2, %xmm1, %xmm1 303; AVX2-NEXT: vpsubd %xmm1, %xmm0, %xmm0 304; AVX2-NEXT: retq 305 %1 = srem <4 x i32> %x, <i32 1, i32 2, i32 4, i32 8> 306 ret <4 x i32> %1 307} 308 309define <4 x i32> @combine_vec_srem_by_pow2b_neg(<4 x i32> %x) { 310; SSE-LABEL: combine_vec_srem_by_pow2b_neg: 311; SSE: # %bb.0: 312; SSE-NEXT: movdqa %xmm0, %xmm1 313; SSE-NEXT: psrad $31, %xmm1 314; SSE-NEXT: movdqa %xmm1, %xmm2 315; SSE-NEXT: psrld $28, %xmm2 316; SSE-NEXT: movdqa %xmm1, %xmm3 317; SSE-NEXT: psrld $30, %xmm3 318; SSE-NEXT: pblendw {{.*#+}} xmm3 = xmm3[0,1,2,3],xmm2[4,5,6,7] 319; SSE-NEXT: movdqa %xmm1, %xmm2 320; SSE-NEXT: psrld $29, %xmm2 321; SSE-NEXT: psrld $31, %xmm1 322; SSE-NEXT: pblendw {{.*#+}} xmm1 = xmm1[0,1,2,3],xmm2[4,5,6,7] 323; SSE-NEXT: pblendw {{.*#+}} xmm1 = xmm1[0,1],xmm3[2,3],xmm1[4,5],xmm3[6,7] 324; SSE-NEXT: paddd %xmm0, %xmm1 325; SSE-NEXT: movdqa %xmm1, %xmm2 326; SSE-NEXT: psrad $4, %xmm2 327; SSE-NEXT: movdqa %xmm1, %xmm3 328; SSE-NEXT: psrad $2, %xmm3 329; SSE-NEXT: pblendw {{.*#+}} xmm3 = xmm3[0,1,2,3],xmm2[4,5,6,7] 330; SSE-NEXT: movdqa %xmm1, %xmm2 331; SSE-NEXT: psrad $3, %xmm2 332; SSE-NEXT: psrad $1, %xmm1 333; SSE-NEXT: pblendw {{.*#+}} xmm1 = xmm1[0,1,2,3],xmm2[4,5,6,7] 334; SSE-NEXT: pblendw {{.*#+}} xmm1 = xmm1[0,1],xmm3[2,3],xmm1[4,5],xmm3[6,7] 335; SSE-NEXT: pmulld {{.*}}(%rip), %xmm1 336; SSE-NEXT: paddd %xmm0, %xmm1 337; SSE-NEXT: movdqa %xmm1, %xmm0 338; SSE-NEXT: retq 339; 340; AVX1-LABEL: combine_vec_srem_by_pow2b_neg: 341; AVX1: # %bb.0: 342; AVX1-NEXT: vpsrad $31, %xmm0, %xmm1 343; AVX1-NEXT: vpsrld $28, %xmm1, %xmm2 344; AVX1-NEXT: vpsrld $30, %xmm1, %xmm3 345; AVX1-NEXT: vpblendw {{.*#+}} xmm2 = xmm3[0,1,2,3],xmm2[4,5,6,7] 346; AVX1-NEXT: vpsrld $29, %xmm1, %xmm3 347; AVX1-NEXT: vpsrld $31, %xmm1, %xmm1 348; AVX1-NEXT: vpblendw {{.*#+}} xmm1 = xmm1[0,1,2,3],xmm3[4,5,6,7] 349; AVX1-NEXT: vpblendw {{.*#+}} xmm1 = xmm1[0,1],xmm2[2,3],xmm1[4,5],xmm2[6,7] 350; AVX1-NEXT: vpaddd %xmm1, %xmm0, %xmm1 351; AVX1-NEXT: vpsrad $4, %xmm1, %xmm2 352; AVX1-NEXT: vpsrad $2, %xmm1, %xmm3 353; AVX1-NEXT: vpblendw {{.*#+}} xmm2 = xmm3[0,1,2,3],xmm2[4,5,6,7] 354; AVX1-NEXT: vpsrad $3, %xmm1, %xmm3 355; AVX1-NEXT: vpsrad $1, %xmm1, %xmm1 356; AVX1-NEXT: vpblendw {{.*#+}} xmm1 = xmm1[0,1,2,3],xmm3[4,5,6,7] 357; AVX1-NEXT: vpblendw {{.*#+}} xmm1 = xmm1[0,1],xmm2[2,3],xmm1[4,5],xmm2[6,7] 358; AVX1-NEXT: vpmulld {{.*}}(%rip), %xmm1, %xmm1 359; AVX1-NEXT: vpaddd %xmm1, %xmm0, %xmm0 360; AVX1-NEXT: retq 361; 362; AVX2-LABEL: combine_vec_srem_by_pow2b_neg: 363; AVX2: # %bb.0: 364; AVX2-NEXT: vpsrad $31, %xmm0, %xmm1 365; AVX2-NEXT: vpsrlvd {{.*}}(%rip), %xmm1, %xmm1 366; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm1 367; AVX2-NEXT: vpsravd {{.*}}(%rip), %xmm1, %xmm1 368; AVX2-NEXT: vpmulld {{.*}}(%rip), %xmm1, %xmm1 369; AVX2-NEXT: vpaddd %xmm1, %xmm0, %xmm0 370; AVX2-NEXT: retq 371 %1 = srem <4 x i32> %x, <i32 -2, i32 -4, i32 -8, i32 -16> 372 ret <4 x i32> %1 373} 374 375; OSS-Fuzz #6883 376; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=6883 377define i32 @ossfuzz6883() { 378; CHECK-LABEL: ossfuzz6883: 379; CHECK: # %bb.0: 380; CHECK-NEXT: movl (%rax), %ecx 381; CHECK-NEXT: movl $2147483647, %eax # imm = 0x7FFFFFFF 382; CHECK-NEXT: xorl %edx, %edx 383; CHECK-NEXT: idivl %ecx 384; CHECK-NEXT: movl %eax, %esi 385; CHECK-NEXT: movl $2147483647, %eax # imm = 0x7FFFFFFF 386; CHECK-NEXT: xorl %edx, %edx 387; CHECK-NEXT: divl %ecx 388; CHECK-NEXT: movl %eax, %edi 389; CHECK-NEXT: movl %esi, %eax 390; CHECK-NEXT: cltd 391; CHECK-NEXT: idivl %edi 392; CHECK-NEXT: movl %edx, %esi 393; CHECK-NEXT: movl %ecx, %eax 394; CHECK-NEXT: cltd 395; CHECK-NEXT: idivl %esi 396; CHECK-NEXT: movl %edx, %edi 397; CHECK-NEXT: movl %ecx, %eax 398; CHECK-NEXT: xorl %edx, %edx 399; CHECK-NEXT: divl %esi 400; CHECK-NEXT: andl %edi, %eax 401; CHECK-NEXT: retq 402 %B17 = or i32 0, 2147483647 403 %L6 = load i32, i32* undef 404 %B11 = sdiv i32 %B17, %L6 405 %B13 = udiv i32 %B17, %L6 406 %B14 = srem i32 %B11, %B13 407 %B16 = srem i32 %L6, %B14 408 %B10 = udiv i32 %L6, %B14 409 %B6 = and i32 %B16, %B10 410 ret i32 %B6 411} 412 413define i1 @bool_srem(i1 %x, i1 %y) { 414; CHECK-LABEL: bool_srem: 415; CHECK: # %bb.0: 416; CHECK-NEXT: xorl %eax, %eax 417; CHECK-NEXT: retq 418 %r = srem i1 %x, %y 419 ret i1 %r 420} 421define <4 x i1> @boolvec_srem(<4 x i1> %x, <4 x i1> %y) { 422; SSE-LABEL: boolvec_srem: 423; SSE: # %bb.0: 424; SSE-NEXT: xorps %xmm0, %xmm0 425; SSE-NEXT: retq 426; 427; AVX-LABEL: boolvec_srem: 428; AVX: # %bb.0: 429; AVX-NEXT: vxorps %xmm0, %xmm0, %xmm0 430; AVX-NEXT: retq 431 %r = srem <4 x i1> %x, %y 432 ret <4 x i1> %r 433} 434 435define i32 @combine_srem_two(i32 %x) { 436; CHECK-LABEL: combine_srem_two: 437; CHECK: # %bb.0: 438; CHECK-NEXT: movl %edi, %eax 439; CHECK-NEXT: movl %edi, %ecx 440; CHECK-NEXT: shrl $31, %ecx 441; CHECK-NEXT: addl %edi, %ecx 442; CHECK-NEXT: andl $-2, %ecx 443; CHECK-NEXT: subl %ecx, %eax 444; CHECK-NEXT: retq 445 %1 = srem i32 %x, 2 446 ret i32 %1 447} 448 449define i32 @combine_srem_negtwo(i32 %x) { 450; CHECK-LABEL: combine_srem_negtwo: 451; CHECK: # %bb.0: 452; CHECK-NEXT: movl %edi, %eax 453; CHECK-NEXT: movl %edi, %ecx 454; CHECK-NEXT: shrl $31, %ecx 455; CHECK-NEXT: addl %edi, %ecx 456; CHECK-NEXT: andl $-2, %ecx 457; CHECK-NEXT: subl %ecx, %eax 458; CHECK-NEXT: retq 459 %1 = srem i32 %x, -2 460 ret i32 %1 461} 462 463define i8 @combine_i8_srem_negpow2(i8 %x) { 464; CHECK-LABEL: combine_i8_srem_negpow2: 465; CHECK: # %bb.0: 466; CHECK-NEXT: movl %edi, %eax 467; CHECK-NEXT: movl %eax, %ecx 468; CHECK-NEXT: sarb $7, %cl 469; CHECK-NEXT: shrb $2, %cl 470; CHECK-NEXT: addb %al, %cl 471; CHECK-NEXT: andb $-64, %cl 472; CHECK-NEXT: subb %cl, %al 473; CHECK-NEXT: # kill: def $al killed $al killed $eax 474; CHECK-NEXT: retq 475 %1 = srem i8 %x, -64 476 ret i8 %1 477} 478 479define i16 @combine_i16_srem_pow2(i16 %x) { 480; CHECK-LABEL: combine_i16_srem_pow2: 481; CHECK: # %bb.0: 482; CHECK-NEXT: movl %edi, %eax 483; CHECK-NEXT: leal 15(%rax), %ecx 484; CHECK-NEXT: testw %ax, %ax 485; CHECK-NEXT: cmovnsl %edi, %ecx 486; CHECK-NEXT: andl $-16, %ecx 487; CHECK-NEXT: subl %ecx, %eax 488; CHECK-NEXT: # kill: def $ax killed $ax killed $rax 489; CHECK-NEXT: retq 490 %1 = srem i16 %x, 16 491 ret i16 %1 492} 493 494define i16 @combine_i16_srem_negpow2(i16 %x) { 495; CHECK-LABEL: combine_i16_srem_negpow2: 496; CHECK: # %bb.0: 497; CHECK-NEXT: movl %edi, %eax 498; CHECK-NEXT: leal 255(%rax), %ecx 499; CHECK-NEXT: testw %ax, %ax 500; CHECK-NEXT: cmovnsl %edi, %ecx 501; CHECK-NEXT: andl $-256, %ecx 502; CHECK-NEXT: subl %ecx, %eax 503; CHECK-NEXT: # kill: def $ax killed $ax killed $rax 504; CHECK-NEXT: retq 505 %1 = srem i16 %x, -256 506 ret i16 %1 507} 508 509define i32 @combine_srem_pow2(i32 %x) { 510; CHECK-LABEL: combine_srem_pow2: 511; CHECK: # %bb.0: 512; CHECK-NEXT: movl %edi, %eax 513; CHECK-NEXT: leal 15(%rax), %ecx 514; CHECK-NEXT: testl %edi, %edi 515; CHECK-NEXT: cmovnsl %edi, %ecx 516; CHECK-NEXT: andl $-16, %ecx 517; CHECK-NEXT: subl %ecx, %eax 518; CHECK-NEXT: # kill: def $eax killed $eax killed $rax 519; CHECK-NEXT: retq 520 %1 = srem i32 %x, 16 521 ret i32 %1 522} 523 524define i32 @combine_srem_negpow2(i32 %x) { 525; CHECK-LABEL: combine_srem_negpow2: 526; CHECK: # %bb.0: 527; CHECK-NEXT: movl %edi, %eax 528; CHECK-NEXT: leal 255(%rax), %ecx 529; CHECK-NEXT: testl %edi, %edi 530; CHECK-NEXT: cmovnsl %edi, %ecx 531; CHECK-NEXT: andl $-256, %ecx 532; CHECK-NEXT: subl %ecx, %eax 533; CHECK-NEXT: # kill: def $eax killed $eax killed $rax 534; CHECK-NEXT: retq 535 %1 = srem i32 %x, -256 536 ret i32 %1 537} 538 539define i64 @combine_i64_srem_pow2(i64 %x) { 540; CHECK-LABEL: combine_i64_srem_pow2: 541; CHECK: # %bb.0: 542; CHECK-NEXT: movq %rdi, %rax 543; CHECK-NEXT: leaq 15(%rdi), %rcx 544; CHECK-NEXT: testq %rdi, %rdi 545; CHECK-NEXT: cmovnsq %rdi, %rcx 546; CHECK-NEXT: andq $-16, %rcx 547; CHECK-NEXT: subq %rcx, %rax 548; CHECK-NEXT: retq 549 %1 = srem i64 %x, 16 550 ret i64 %1 551} 552 553define i64 @combine_i64_srem_negpow2(i64 %x) { 554; CHECK-LABEL: combine_i64_srem_negpow2: 555; CHECK: # %bb.0: 556; CHECK-NEXT: movq %rdi, %rax 557; CHECK-NEXT: leaq 255(%rdi), %rcx 558; CHECK-NEXT: testq %rdi, %rdi 559; CHECK-NEXT: cmovnsq %rdi, %rcx 560; CHECK-NEXT: andq $-256, %rcx 561; CHECK-NEXT: subq %rcx, %rax 562; CHECK-NEXT: retq 563 %1 = srem i64 %x, -256 564 ret i64 %1 565} 566