389 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+cmov < %s | FileCheck %s --check-prefixes=CHECK,X863; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK,X644 5;------------------------------------------------------------------------------;6; Odd divisors7;------------------------------------------------------------------------------;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 = 0xCCCCCCCD13; X86-NEXT: addl $429496729, %ecx # imm = 0x1999999914; X86-NEXT: xorl %eax, %eax15; X86-NEXT: cmpl $858993459, %ecx # imm = 0x3333333316; X86-NEXT: setb %al17; X86-NEXT: retl18;19; X64-LABEL: test_srem_odd:20; X64: # %bb.0:21; X64-NEXT: imull $-858993459, %edi, %ecx # imm = 0xCCCCCCCD22; X64-NEXT: addl $429496729, %ecx # imm = 0x1999999923; X64-NEXT: xorl %eax, %eax24; X64-NEXT: cmpl $858993459, %ecx # imm = 0x3333333325; X64-NEXT: setb %al26; X64-NEXT: retq27 %srem = srem i32 %X, 528 %cmp = icmp eq i32 %srem, 029 %ret = zext i1 %cmp to i3230 ret i32 %ret31}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 = 0xC28F5C2937; X86-NEXT: addl $85899345, %ecx # imm = 0x51EB85138; X86-NEXT: xorl %eax, %eax39; X86-NEXT: cmpl $171798691, %ecx # imm = 0xA3D70A340; X86-NEXT: setb %al41; X86-NEXT: retl42;43; X64-LABEL: test_srem_odd_25:44; X64: # %bb.0:45; X64-NEXT: imull $-1030792151, %edi, %ecx # imm = 0xC28F5C2946; X64-NEXT: addl $85899345, %ecx # imm = 0x51EB85147; X64-NEXT: xorl %eax, %eax48; X64-NEXT: cmpl $171798691, %ecx # imm = 0xA3D70A349; X64-NEXT: setb %al50; X64-NEXT: retq51 %srem = srem i32 %X, 2552 %cmp = icmp eq i32 %srem, 053 %ret = zext i1 %cmp to i3254 ret i32 %ret55}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 = 0x6AAAAAAB62; X86-NEXT: incl %ecx63; X86-NEXT: xorl %eax, %eax64; X86-NEXT: cmpl $3, %ecx65; X86-NEXT: setb %al66; X86-NEXT: retl67;68; X64-LABEL: test_srem_odd_bit30:69; X64: # %bb.0:70; X64-NEXT: imull $1789569707, %edi, %ecx # imm = 0x6AAAAAAB71; X64-NEXT: incl %ecx72; X64-NEXT: xorl %eax, %eax73; X64-NEXT: cmpl $3, %ecx74; X64-NEXT: setb %al75; X64-NEXT: retq76 %srem = srem i32 %X, 107374182777 %cmp = icmp eq i32 %srem, 078 %ret = zext i1 %cmp to i3279 ret i32 %ret80}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 = 0xD555555587; X86-NEXT: incl %ecx88; X86-NEXT: xorl %eax, %eax89; X86-NEXT: cmpl $3, %ecx90; X86-NEXT: setb %al91; X86-NEXT: retl92;93; X64-LABEL: test_srem_odd_bit31:94; X64: # %bb.0:95; X64-NEXT: imull $-715827883, %edi, %ecx # imm = 0xD555555596; X64-NEXT: incl %ecx97; X64-NEXT: xorl %eax, %eax98; X64-NEXT: cmpl $3, %ecx99; X64-NEXT: setb %al100; X64-NEXT: retq101 %srem = srem i32 %X, 2147483651102 %cmp = icmp eq i32 %srem, 0103 %ret = zext i1 %cmp to i32104 ret i32 %ret105}106 107;------------------------------------------------------------------------------;108; Even divisors109;------------------------------------------------------------------------------;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 = 0x6DB7115; X86-NEXT: addl $4680, %eax # imm = 0x1248116; X86-NEXT: rorw %ax117; X86-NEXT: movzwl %ax, %ecx118; X86-NEXT: xorl %eax, %eax119; X86-NEXT: cmpl $4681, %ecx # imm = 0x1249120; X86-NEXT: setae %al121; X86-NEXT: # kill: def $ax killed $ax killed $eax122; X86-NEXT: retl123;124; X64-LABEL: test_srem_even:125; X64: # %bb.0:126; X64-NEXT: imull $28087, %edi, %eax # imm = 0x6DB7127; X64-NEXT: addl $4680, %eax # imm = 0x1248128; X64-NEXT: rorw %ax129; X64-NEXT: movzwl %ax, %ecx130; X64-NEXT: xorl %eax, %eax131; X64-NEXT: cmpl $4681, %ecx # imm = 0x1249132; X64-NEXT: setae %al133; X64-NEXT: # kill: def $ax killed $ax killed $eax134; X64-NEXT: retq135 %srem = srem i16 %X, 14136 %cmp = icmp ne i16 %srem, 0137 %ret = zext i1 %cmp to i16138 ret i16 %ret139}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 = 0xC28F5C29145; X86-NEXT: addl $85899344, %ecx # imm = 0x51EB850146; X86-NEXT: rorl $2, %ecx147; X86-NEXT: xorl %eax, %eax148; X86-NEXT: cmpl $42949673, %ecx # imm = 0x28F5C29149; X86-NEXT: setb %al150; X86-NEXT: retl151;152; X64-LABEL: test_srem_even_100:153; X64: # %bb.0:154; X64-NEXT: imull $-1030792151, %edi, %ecx # imm = 0xC28F5C29155; X64-NEXT: addl $85899344, %ecx # imm = 0x51EB850156; X64-NEXT: rorl $2, %ecx157; X64-NEXT: xorl %eax, %eax158; X64-NEXT: cmpl $42949673, %ecx # imm = 0x28F5C29159; X64-NEXT: setb %al160; X64-NEXT: retq161 %srem = srem i32 %X, 100162 %cmp = icmp eq i32 %srem, 0163 %ret = zext i1 %cmp to i32164 ret i32 %ret165}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 = 0xFCEC4EC5172; X86-NEXT: addl $8, %ecx173; X86-NEXT: rorl $3, %ecx174; X86-NEXT: xorl %eax, %eax175; X86-NEXT: cmpl $3, %ecx176; X86-NEXT: setb %al177; X86-NEXT: retl178;179; X64-LABEL: test_srem_even_bit30:180; X64: # %bb.0:181; X64-NEXT: imull $-51622203, %edi, %ecx # imm = 0xFCEC4EC5182; X64-NEXT: addl $8, %ecx183; X64-NEXT: rorl $3, %ecx184; X64-NEXT: xorl %eax, %eax185; X64-NEXT: cmpl $3, %ecx186; X64-NEXT: setb %al187; X64-NEXT: retq188 %srem = srem i32 %X, 1073741928189 %cmp = icmp eq i32 %srem, 0190 %ret = zext i1 %cmp to i32191 ret i32 %ret192}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 = 0xC5050505199; X86-NEXT: addl $2, %ecx200; X86-NEXT: rorl %ecx201; X86-NEXT: xorl %eax, %eax202; X86-NEXT: cmpl $3, %ecx203; X86-NEXT: setb %al204; X86-NEXT: retl205;206; X64-LABEL: test_srem_even_bit31:207; X64: # %bb.0:208; X64-NEXT: imull $-989526779, %edi, %ecx # imm = 0xC5050505209; X64-NEXT: addl $2, %ecx210; X64-NEXT: rorl %ecx211; X64-NEXT: xorl %eax, %eax212; X64-NEXT: cmpl $3, %ecx213; X64-NEXT: setb %al214; X64-NEXT: retq215 %srem = srem i32 %X, 2147483750216 %cmp = icmp eq i32 %srem, 0217 %ret = zext i1 %cmp to i32218 ret i32 %ret219}220 221;------------------------------------------------------------------------------;222; Special case223;------------------------------------------------------------------------------;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 = 0xCCCCCCCD230; X86-NEXT: addl $429496729, %ecx # imm = 0x19999999231; X86-NEXT: xorl %eax, %eax232; X86-NEXT: cmpl $858993459, %ecx # imm = 0x33333333233; X86-NEXT: setae %al234; X86-NEXT: retl235;236; X64-LABEL: test_srem_odd_setne:237; X64: # %bb.0:238; X64-NEXT: imull $-858993459, %edi, %ecx # imm = 0xCCCCCCCD239; X64-NEXT: addl $429496729, %ecx # imm = 0x19999999240; X64-NEXT: xorl %eax, %eax241; X64-NEXT: cmpl $858993459, %ecx # imm = 0x33333333242; X64-NEXT: setae %al243; X64-NEXT: retq244 %srem = srem i32 %X, 5245 %cmp = icmp ne i32 %srem, 0246 %ret = zext i1 %cmp to i32247 ret i32 %ret248}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 = 0xCCCCCCCD255; X86-NEXT: addl $429496729, %ecx # imm = 0x19999999256; X86-NEXT: xorl %eax, %eax257; X86-NEXT: cmpl $858993459, %ecx # imm = 0x33333333258; X86-NEXT: setae %al259; X86-NEXT: retl260;261; X64-LABEL: test_srem_negative_odd:262; X64: # %bb.0:263; X64-NEXT: imull $-858993459, %edi, %ecx # imm = 0xCCCCCCCD264; X64-NEXT: addl $429496729, %ecx # imm = 0x19999999265; X64-NEXT: xorl %eax, %eax266; X64-NEXT: cmpl $858993459, %ecx # imm = 0x33333333267; X64-NEXT: setae %al268; X64-NEXT: retq269 %srem = srem i32 %X, -5270 %cmp = icmp ne i32 %srem, 0271 %ret = zext i1 %cmp to i32272 ret i32 %ret273}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 = 0xB6DB6DB7278; X86-NEXT: addl $306783378, %ecx # imm = 0x12492492279; X86-NEXT: rorl %ecx280; X86-NEXT: xorl %eax, %eax281; X86-NEXT: cmpl $306783379, %ecx # imm = 0x12492493282; X86-NEXT: setae %al283; X86-NEXT: retl284;285; X64-LABEL: test_srem_negative_even:286; X64: # %bb.0:287; X64-NEXT: imull $-1227133513, %edi, %ecx # imm = 0xB6DB6DB7288; X64-NEXT: addl $306783378, %ecx # imm = 0x12492492289; X64-NEXT: rorl %ecx290; X64-NEXT: xorl %eax, %eax291; X64-NEXT: cmpl $306783379, %ecx # imm = 0x12492493292; X64-NEXT: setae %al293; X64-NEXT: retq294 %srem = srem i32 %X, -14295 %cmp = icmp ne i32 %srem, 0296 %ret = zext i1 %cmp to i32297 ret i32 %ret298}299 300;------------------------------------------------------------------------------;301; Negative tests302;------------------------------------------------------------------------------;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, %eax309; CHECK-NEXT: ret{{[l|q]}}310 %srem = srem i32 %X, 1311 %cmp = icmp eq i32 %srem, 0312 %ret = zext i1 %cmp to i32313 ret i32 %ret314}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), %ecx321; X86-NEXT: leal 15(%ecx), %edx322; X86-NEXT: testl %ecx, %ecx323; X86-NEXT: cmovnsl %ecx, %edx324; X86-NEXT: andl $-16, %edx325; X86-NEXT: xorl %eax, %eax326; X86-NEXT: cmpl %edx, %ecx327; X86-NEXT: sete %al328; X86-NEXT: retl329;330; X64-LABEL: test_srem_pow2:331; X64: # %bb.0:332; X64-NEXT: # kill: def $edi killed $edi def $rdi333; X64-NEXT: leal 15(%rdi), %ecx334; X64-NEXT: testl %edi, %edi335; X64-NEXT: cmovnsl %edi, %ecx336; X64-NEXT: andl $-16, %ecx337; X64-NEXT: xorl %eax, %eax338; X64-NEXT: cmpl %ecx, %edi339; X64-NEXT: sete %al340; X64-NEXT: retq341 %srem = srem i32 %X, 16342 %cmp = icmp eq i32 %srem, 0343 %ret = zext i1 %cmp to i32344 ret i32 %ret345}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), %ecx352; X86-NEXT: leal 2147483647(%ecx), %edx353; X86-NEXT: testl %ecx, %ecx354; X86-NEXT: cmovnsl %ecx, %edx355; X86-NEXT: andl $-2147483648, %edx # imm = 0x80000000356; X86-NEXT: xorl %eax, %eax357; X86-NEXT: addl %ecx, %edx358; X86-NEXT: sete %al359; X86-NEXT: retl360;361; X64-LABEL: test_srem_int_min:362; X64: # %bb.0:363; X64-NEXT: # kill: def $edi killed $edi def $rdi364; X64-NEXT: leal 2147483647(%rdi), %ecx365; X64-NEXT: testl %edi, %edi366; X64-NEXT: cmovnsl %edi, %ecx367; X64-NEXT: andl $-2147483648, %ecx # imm = 0x80000000368; X64-NEXT: xorl %eax, %eax369; X64-NEXT: addl %edi, %ecx370; X64-NEXT: sete %al371; X64-NEXT: retq372 %srem = srem i32 %X, 2147483648373 %cmp = icmp eq i32 %srem, 0374 %ret = zext i1 %cmp to i32375 ret i32 %ret376}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, %eax383; CHECK-NEXT: ret{{[l|q]}}384 %srem = srem i32 %X, 4294967295385 %cmp = icmp eq i32 %srem, 0386 %ret = zext i1 %cmp to i32387 ret i32 %ret388}389