1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+cmov < %s | FileCheck %s --check-prefixes=CHECK,X86 3; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK,X64 4 5;------------------------------------------------------------------------------; 6; Odd divisors 7;------------------------------------------------------------------------------; 8 9define i32 @test_srem_odd(i32 %X) nounwind { 10; X86-LABEL: test_srem_odd: 11; X86: # %bb.0: 12; X86-NEXT: imull $-858993459, {{[0-9]+}}(%esp), %ecx # imm = 0xCCCCCCCD 13; X86-NEXT: addl $429496729, %ecx # imm = 0x19999999 14; X86-NEXT: xorl %eax, %eax 15; X86-NEXT: cmpl $858993459, %ecx # imm = 0x33333333 16; X86-NEXT: setb %al 17; X86-NEXT: retl 18; 19; X64-LABEL: test_srem_odd: 20; X64: # %bb.0: 21; X64-NEXT: imull $-858993459, %edi, %ecx # imm = 0xCCCCCCCD 22; X64-NEXT: addl $429496729, %ecx # imm = 0x19999999 23; X64-NEXT: xorl %eax, %eax 24; X64-NEXT: cmpl $858993459, %ecx # imm = 0x33333333 25; X64-NEXT: setb %al 26; X64-NEXT: retq 27 %srem = srem i32 %X, 5 28 %cmp = icmp eq i32 %srem, 0 29 %ret = zext i1 %cmp to i32 30 ret i32 %ret 31} 32 33define i32 @test_srem_odd_25(i32 %X) nounwind { 34; X86-LABEL: test_srem_odd_25: 35; X86: # %bb.0: 36; X86-NEXT: imull $-1030792151, {{[0-9]+}}(%esp), %ecx # imm = 0xC28F5C29 37; X86-NEXT: addl $85899345, %ecx # imm = 0x51EB851 38; X86-NEXT: xorl %eax, %eax 39; X86-NEXT: cmpl $171798691, %ecx # imm = 0xA3D70A3 40; X86-NEXT: setb %al 41; X86-NEXT: retl 42; 43; X64-LABEL: test_srem_odd_25: 44; X64: # %bb.0: 45; X64-NEXT: imull $-1030792151, %edi, %ecx # imm = 0xC28F5C29 46; X64-NEXT: addl $85899345, %ecx # imm = 0x51EB851 47; X64-NEXT: xorl %eax, %eax 48; X64-NEXT: cmpl $171798691, %ecx # imm = 0xA3D70A3 49; X64-NEXT: setb %al 50; X64-NEXT: retq 51 %srem = srem i32 %X, 25 52 %cmp = icmp eq i32 %srem, 0 53 %ret = zext i1 %cmp to i32 54 ret i32 %ret 55} 56 57; This is like test_srem_odd, except the divisor has bit 30 set. 58define i32 @test_srem_odd_bit30(i32 %X) nounwind { 59; X86-LABEL: test_srem_odd_bit30: 60; X86: # %bb.0: 61; X86-NEXT: imull $1789569707, {{[0-9]+}}(%esp), %ecx # imm = 0x6AAAAAAB 62; X86-NEXT: incl %ecx 63; X86-NEXT: xorl %eax, %eax 64; X86-NEXT: cmpl $3, %ecx 65; X86-NEXT: setb %al 66; X86-NEXT: retl 67; 68; X64-LABEL: test_srem_odd_bit30: 69; X64: # %bb.0: 70; X64-NEXT: imull $1789569707, %edi, %ecx # imm = 0x6AAAAAAB 71; X64-NEXT: incl %ecx 72; X64-NEXT: xorl %eax, %eax 73; X64-NEXT: cmpl $3, %ecx 74; X64-NEXT: setb %al 75; X64-NEXT: retq 76 %srem = srem i32 %X, 1073741827 77 %cmp = icmp eq i32 %srem, 0 78 %ret = zext i1 %cmp to i32 79 ret i32 %ret 80} 81 82; This is like test_srem_odd, except the divisor has bit 31 set. 83define i32 @test_srem_odd_bit31(i32 %X) nounwind { 84; X86-LABEL: test_srem_odd_bit31: 85; X86: # %bb.0: 86; X86-NEXT: imull $-715827883, {{[0-9]+}}(%esp), %ecx # imm = 0xD5555555 87; X86-NEXT: incl %ecx 88; X86-NEXT: xorl %eax, %eax 89; X86-NEXT: cmpl $3, %ecx 90; X86-NEXT: setb %al 91; X86-NEXT: retl 92; 93; X64-LABEL: test_srem_odd_bit31: 94; X64: # %bb.0: 95; X64-NEXT: imull $-715827883, %edi, %ecx # imm = 0xD5555555 96; X64-NEXT: incl %ecx 97; X64-NEXT: xorl %eax, %eax 98; X64-NEXT: cmpl $3, %ecx 99; X64-NEXT: setb %al 100; X64-NEXT: retq 101 %srem = srem i32 %X, 2147483651 102 %cmp = icmp eq i32 %srem, 0 103 %ret = zext i1 %cmp to i32 104 ret i32 %ret 105} 106 107;------------------------------------------------------------------------------; 108; Even divisors 109;------------------------------------------------------------------------------; 110 111define i16 @test_srem_even(i16 %X) nounwind { 112; X86-LABEL: test_srem_even: 113; X86: # %bb.0: 114; X86-NEXT: imull $28087, {{[0-9]+}}(%esp), %eax # imm = 0x6DB7 115; X86-NEXT: addl $4680, %eax # imm = 0x1248 116; X86-NEXT: rorw %ax 117; X86-NEXT: movzwl %ax, %ecx 118; X86-NEXT: xorl %eax, %eax 119; X86-NEXT: cmpl $4681, %ecx # imm = 0x1249 120; X86-NEXT: setae %al 121; X86-NEXT: # kill: def $ax killed $ax killed $eax 122; X86-NEXT: retl 123; 124; X64-LABEL: test_srem_even: 125; X64: # %bb.0: 126; X64-NEXT: imull $28087, %edi, %eax # imm = 0x6DB7 127; X64-NEXT: addl $4680, %eax # imm = 0x1248 128; X64-NEXT: rorw %ax 129; X64-NEXT: movzwl %ax, %ecx 130; X64-NEXT: xorl %eax, %eax 131; X64-NEXT: cmpl $4681, %ecx # imm = 0x1249 132; X64-NEXT: setae %al 133; X64-NEXT: # kill: def $ax killed $ax killed $eax 134; X64-NEXT: retq 135 %srem = srem i16 %X, 14 136 %cmp = icmp ne i16 %srem, 0 137 %ret = zext i1 %cmp to i16 138 ret i16 %ret 139} 140 141define i32 @test_srem_even_100(i32 %X) nounwind { 142; X86-LABEL: test_srem_even_100: 143; X86: # %bb.0: 144; X86-NEXT: imull $-1030792151, {{[0-9]+}}(%esp), %ecx # imm = 0xC28F5C29 145; X86-NEXT: addl $85899344, %ecx # imm = 0x51EB850 146; X86-NEXT: rorl $2, %ecx 147; X86-NEXT: xorl %eax, %eax 148; X86-NEXT: cmpl $42949673, %ecx # imm = 0x28F5C29 149; X86-NEXT: setb %al 150; X86-NEXT: retl 151; 152; X64-LABEL: test_srem_even_100: 153; X64: # %bb.0: 154; X64-NEXT: imull $-1030792151, %edi, %ecx # imm = 0xC28F5C29 155; X64-NEXT: addl $85899344, %ecx # imm = 0x51EB850 156; X64-NEXT: rorl $2, %ecx 157; X64-NEXT: xorl %eax, %eax 158; X64-NEXT: cmpl $42949673, %ecx # imm = 0x28F5C29 159; X64-NEXT: setb %al 160; X64-NEXT: retq 161 %srem = srem i32 %X, 100 162 %cmp = icmp eq i32 %srem, 0 163 %ret = zext i1 %cmp to i32 164 ret i32 %ret 165} 166 167; This is like test_srem_even, except the divisor has bit 30 set. 168define i32 @test_srem_even_bit30(i32 %X) nounwind { 169; X86-LABEL: test_srem_even_bit30: 170; X86: # %bb.0: 171; X86-NEXT: imull $-51622203, {{[0-9]+}}(%esp), %ecx # imm = 0xFCEC4EC5 172; X86-NEXT: addl $8, %ecx 173; X86-NEXT: rorl $3, %ecx 174; X86-NEXT: xorl %eax, %eax 175; X86-NEXT: cmpl $3, %ecx 176; X86-NEXT: setb %al 177; X86-NEXT: retl 178; 179; X64-LABEL: test_srem_even_bit30: 180; X64: # %bb.0: 181; X64-NEXT: imull $-51622203, %edi, %ecx # imm = 0xFCEC4EC5 182; X64-NEXT: addl $8, %ecx 183; X64-NEXT: rorl $3, %ecx 184; X64-NEXT: xorl %eax, %eax 185; X64-NEXT: cmpl $3, %ecx 186; X64-NEXT: setb %al 187; X64-NEXT: retq 188 %srem = srem i32 %X, 1073741928 189 %cmp = icmp eq i32 %srem, 0 190 %ret = zext i1 %cmp to i32 191 ret i32 %ret 192} 193 194; This is like test_srem_odd, except the divisor has bit 31 set. 195define i32 @test_srem_even_bit31(i32 %X) nounwind { 196; X86-LABEL: test_srem_even_bit31: 197; X86: # %bb.0: 198; X86-NEXT: imull $-989526779, {{[0-9]+}}(%esp), %ecx # imm = 0xC5050505 199; X86-NEXT: addl $2, %ecx 200; X86-NEXT: rorl %ecx 201; X86-NEXT: xorl %eax, %eax 202; X86-NEXT: cmpl $3, %ecx 203; X86-NEXT: setb %al 204; X86-NEXT: retl 205; 206; X64-LABEL: test_srem_even_bit31: 207; X64: # %bb.0: 208; X64-NEXT: imull $-989526779, %edi, %ecx # imm = 0xC5050505 209; X64-NEXT: addl $2, %ecx 210; X64-NEXT: rorl %ecx 211; X64-NEXT: xorl %eax, %eax 212; X64-NEXT: cmpl $3, %ecx 213; X64-NEXT: setb %al 214; X64-NEXT: retq 215 %srem = srem i32 %X, 2147483750 216 %cmp = icmp eq i32 %srem, 0 217 %ret = zext i1 %cmp to i32 218 ret i32 %ret 219} 220 221;------------------------------------------------------------------------------; 222; Special case 223;------------------------------------------------------------------------------; 224 225; 'NE' predicate is fine too. 226define i32 @test_srem_odd_setne(i32 %X) nounwind { 227; X86-LABEL: test_srem_odd_setne: 228; X86: # %bb.0: 229; X86-NEXT: imull $-858993459, {{[0-9]+}}(%esp), %ecx # imm = 0xCCCCCCCD 230; X86-NEXT: addl $429496729, %ecx # imm = 0x19999999 231; X86-NEXT: xorl %eax, %eax 232; X86-NEXT: cmpl $858993459, %ecx # imm = 0x33333333 233; X86-NEXT: setae %al 234; X86-NEXT: retl 235; 236; X64-LABEL: test_srem_odd_setne: 237; X64: # %bb.0: 238; X64-NEXT: imull $-858993459, %edi, %ecx # imm = 0xCCCCCCCD 239; X64-NEXT: addl $429496729, %ecx # imm = 0x19999999 240; X64-NEXT: xorl %eax, %eax 241; X64-NEXT: cmpl $858993459, %ecx # imm = 0x33333333 242; X64-NEXT: setae %al 243; X64-NEXT: retq 244 %srem = srem i32 %X, 5 245 %cmp = icmp ne i32 %srem, 0 246 %ret = zext i1 %cmp to i32 247 ret i32 %ret 248} 249 250; The fold is only valid for positive divisors, negative-ones should be negated. 251define i32 @test_srem_negative_odd(i32 %X) nounwind { 252; X86-LABEL: test_srem_negative_odd: 253; X86: # %bb.0: 254; X86-NEXT: imull $-858993459, {{[0-9]+}}(%esp), %ecx # imm = 0xCCCCCCCD 255; X86-NEXT: addl $429496729, %ecx # imm = 0x19999999 256; X86-NEXT: xorl %eax, %eax 257; X86-NEXT: cmpl $858993459, %ecx # imm = 0x33333333 258; X86-NEXT: setae %al 259; X86-NEXT: retl 260; 261; X64-LABEL: test_srem_negative_odd: 262; X64: # %bb.0: 263; X64-NEXT: imull $-858993459, %edi, %ecx # imm = 0xCCCCCCCD 264; X64-NEXT: addl $429496729, %ecx # imm = 0x19999999 265; X64-NEXT: xorl %eax, %eax 266; X64-NEXT: cmpl $858993459, %ecx # imm = 0x33333333 267; X64-NEXT: setae %al 268; X64-NEXT: retq 269 %srem = srem i32 %X, -5 270 %cmp = icmp ne i32 %srem, 0 271 %ret = zext i1 %cmp to i32 272 ret i32 %ret 273} 274define i32 @test_srem_negative_even(i32 %X) nounwind { 275; X86-LABEL: test_srem_negative_even: 276; X86: # %bb.0: 277; X86-NEXT: imull $-1227133513, {{[0-9]+}}(%esp), %ecx # imm = 0xB6DB6DB7 278; X86-NEXT: addl $306783378, %ecx # imm = 0x12492492 279; X86-NEXT: rorl %ecx 280; X86-NEXT: xorl %eax, %eax 281; X86-NEXT: cmpl $306783379, %ecx # imm = 0x12492493 282; X86-NEXT: setae %al 283; X86-NEXT: retl 284; 285; X64-LABEL: test_srem_negative_even: 286; X64: # %bb.0: 287; X64-NEXT: imull $-1227133513, %edi, %ecx # imm = 0xB6DB6DB7 288; X64-NEXT: addl $306783378, %ecx # imm = 0x12492492 289; X64-NEXT: rorl %ecx 290; X64-NEXT: xorl %eax, %eax 291; X64-NEXT: cmpl $306783379, %ecx # imm = 0x12492493 292; X64-NEXT: setae %al 293; X64-NEXT: retq 294 %srem = srem i32 %X, -14 295 %cmp = icmp ne i32 %srem, 0 296 %ret = zext i1 %cmp to i32 297 ret i32 %ret 298} 299 300;------------------------------------------------------------------------------; 301; Negative tests 302;------------------------------------------------------------------------------; 303 304; We can lower remainder of division by one much better elsewhere. 305define i32 @test_srem_one(i32 %X) nounwind { 306; CHECK-LABEL: test_srem_one: 307; CHECK: # %bb.0: 308; CHECK-NEXT: movl $1, %eax 309; CHECK-NEXT: ret{{[l|q]}} 310 %srem = srem i32 %X, 1 311 %cmp = icmp eq i32 %srem, 0 312 %ret = zext i1 %cmp to i32 313 ret i32 %ret 314} 315 316; We can lower remainder of division by powers of two much better elsewhere. 317define i32 @test_srem_pow2(i32 %X) nounwind { 318; X86-LABEL: test_srem_pow2: 319; X86: # %bb.0: 320; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 321; X86-NEXT: leal 15(%ecx), %edx 322; X86-NEXT: testl %ecx, %ecx 323; X86-NEXT: cmovnsl %ecx, %edx 324; X86-NEXT: andl $-16, %edx 325; X86-NEXT: xorl %eax, %eax 326; X86-NEXT: cmpl %edx, %ecx 327; X86-NEXT: sete %al 328; X86-NEXT: retl 329; 330; X64-LABEL: test_srem_pow2: 331; X64: # %bb.0: 332; X64-NEXT: # kill: def $edi killed $edi def $rdi 333; X64-NEXT: leal 15(%rdi), %ecx 334; X64-NEXT: testl %edi, %edi 335; X64-NEXT: cmovnsl %edi, %ecx 336; X64-NEXT: andl $-16, %ecx 337; X64-NEXT: xorl %eax, %eax 338; X64-NEXT: cmpl %ecx, %edi 339; X64-NEXT: sete %al 340; X64-NEXT: retq 341 %srem = srem i32 %X, 16 342 %cmp = icmp eq i32 %srem, 0 343 %ret = zext i1 %cmp to i32 344 ret i32 %ret 345} 346 347; The fold is only valid for positive divisors, and we can't negate INT_MIN. 348define i32 @test_srem_int_min(i32 %X) nounwind { 349; X86-LABEL: test_srem_int_min: 350; X86: # %bb.0: 351; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx 352; X86-NEXT: leal 2147483647(%ecx), %edx 353; X86-NEXT: testl %ecx, %ecx 354; X86-NEXT: cmovnsl %ecx, %edx 355; X86-NEXT: andl $-2147483648, %edx # imm = 0x80000000 356; X86-NEXT: xorl %eax, %eax 357; X86-NEXT: addl %ecx, %edx 358; X86-NEXT: sete %al 359; X86-NEXT: retl 360; 361; X64-LABEL: test_srem_int_min: 362; X64: # %bb.0: 363; X64-NEXT: # kill: def $edi killed $edi def $rdi 364; X64-NEXT: leal 2147483647(%rdi), %ecx 365; X64-NEXT: testl %edi, %edi 366; X64-NEXT: cmovnsl %edi, %ecx 367; X64-NEXT: andl $-2147483648, %ecx # imm = 0x80000000 368; X64-NEXT: xorl %eax, %eax 369; X64-NEXT: addl %edi, %ecx 370; X64-NEXT: sete %al 371; X64-NEXT: retq 372 %srem = srem i32 %X, 2147483648 373 %cmp = icmp eq i32 %srem, 0 374 %ret = zext i1 %cmp to i32 375 ret i32 %ret 376} 377 378; We can lower remainder of division by all-ones much better elsewhere. 379define i32 @test_srem_allones(i32 %X) nounwind { 380; CHECK-LABEL: test_srem_allones: 381; CHECK: # %bb.0: 382; CHECK-NEXT: movl $1, %eax 383; CHECK-NEXT: ret{{[l|q]}} 384 %srem = srem i32 %X, 4294967295 385 %cmp = icmp eq i32 %srem, 0 386 %ret = zext i1 %cmp to i32 387 ret i32 %ret 388} 389