1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; Check that 32-bit division is bypassed correctly. 3; RUN: llc < %s -mattr=+idivl-to-divb -mtriple=i686-linux | FileCheck %s 4 5define i32 @Test_get_quotient(i32 %a, i32 %b) nounwind { 6; CHECK-LABEL: Test_get_quotient: 7; CHECK: # %bb.0: 8; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 9; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 10; CHECK-NEXT: movl %eax, %edx 11; CHECK-NEXT: orl %ecx, %edx 12; CHECK-NEXT: testl $-256, %edx 13; CHECK-NEXT: je .LBB0_1 14; CHECK-NEXT: # %bb.2: 15; CHECK-NEXT: cltd 16; CHECK-NEXT: idivl %ecx 17; CHECK-NEXT: retl 18; CHECK-NEXT: .LBB0_1: 19; CHECK-NEXT: movzbl %al, %eax 20; CHECK-NEXT: # kill: def $eax killed $eax def $ax 21; CHECK-NEXT: divb %cl 22; CHECK-NEXT: movzbl %al, %eax 23; CHECK-NEXT: retl 24 %result = sdiv i32 %a, %b 25 ret i32 %result 26} 27 28define i32 @Test_get_remainder(i32 %a, i32 %b) nounwind { 29; CHECK-LABEL: Test_get_remainder: 30; CHECK: # %bb.0: 31; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 32; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 33; CHECK-NEXT: movl %eax, %edx 34; CHECK-NEXT: orl %ecx, %edx 35; CHECK-NEXT: testl $-256, %edx 36; CHECK-NEXT: je .LBB1_1 37; CHECK-NEXT: # %bb.2: 38; CHECK-NEXT: cltd 39; CHECK-NEXT: idivl %ecx 40; CHECK-NEXT: movl %edx, %eax 41; CHECK-NEXT: retl 42; CHECK-NEXT: .LBB1_1: 43; CHECK-NEXT: movzbl %al, %eax 44; CHECK-NEXT: # kill: def $eax killed $eax def $ax 45; CHECK-NEXT: divb %cl 46; CHECK-NEXT: movzbl %ah, %eax 47; CHECK-NEXT: retl 48 %result = srem i32 %a, %b 49 ret i32 %result 50} 51 52define i32 @Test_get_quotient_and_remainder(i32 %a, i32 %b) nounwind { 53; CHECK-LABEL: Test_get_quotient_and_remainder: 54; CHECK: # %bb.0: 55; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 56; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 57; CHECK-NEXT: movl %eax, %edx 58; CHECK-NEXT: orl %ecx, %edx 59; CHECK-NEXT: testl $-256, %edx 60; CHECK-NEXT: je .LBB2_1 61; CHECK-NEXT: # %bb.2: 62; CHECK-NEXT: cltd 63; CHECK-NEXT: idivl %ecx 64; CHECK-NEXT: addl %edx, %eax 65; CHECK-NEXT: retl 66; CHECK-NEXT: .LBB2_1: 67; CHECK-NEXT: movzbl %al, %eax 68; CHECK-NEXT: # kill: def $eax killed $eax def $ax 69; CHECK-NEXT: divb %cl 70; CHECK-NEXT: movzbl %ah, %edx 71; CHECK-NEXT: movzbl %al, %eax 72; CHECK-NEXT: addl %edx, %eax 73; CHECK-NEXT: retl 74 %resultdiv = sdiv i32 %a, %b 75 %resultrem = srem i32 %a, %b 76 %result = add i32 %resultdiv, %resultrem 77 ret i32 %result 78} 79 80define i32 @Test_use_div_and_idiv(i32 %a, i32 %b) nounwind { 81; CHECK-LABEL: Test_use_div_and_idiv: 82; CHECK: # %bb.0: 83; CHECK-NEXT: pushl %ebx 84; CHECK-NEXT: pushl %edi 85; CHECK-NEXT: pushl %esi 86; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ebx 87; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 88; CHECK-NEXT: movl %ecx, %edi 89; CHECK-NEXT: orl %ebx, %edi 90; CHECK-NEXT: testl $-256, %edi 91; CHECK-NEXT: je .LBB3_1 92; CHECK-NEXT: # %bb.2: 93; CHECK-NEXT: movl %ecx, %eax 94; CHECK-NEXT: cltd 95; CHECK-NEXT: idivl %ebx 96; CHECK-NEXT: movl %eax, %esi 97; CHECK-NEXT: testl $-256, %edi 98; CHECK-NEXT: je .LBB3_4 99; CHECK-NEXT: .LBB3_5: 100; CHECK-NEXT: xorl %edx, %edx 101; CHECK-NEXT: movl %ecx, %eax 102; CHECK-NEXT: divl %ebx 103; CHECK-NEXT: jmp .LBB3_6 104; CHECK-NEXT: .LBB3_1: 105; CHECK-NEXT: movzbl %cl, %eax 106; CHECK-NEXT: # kill: def $eax killed $eax def $ax 107; CHECK-NEXT: divb %bl 108; CHECK-NEXT: movzbl %al, %esi 109; CHECK-NEXT: testl $-256, %edi 110; CHECK-NEXT: jne .LBB3_5 111; CHECK-NEXT: .LBB3_4: 112; CHECK-NEXT: movzbl %cl, %eax 113; CHECK-NEXT: # kill: def $eax killed $eax def $ax 114; CHECK-NEXT: divb %bl 115; CHECK-NEXT: movzbl %al, %eax 116; CHECK-NEXT: .LBB3_6: 117; CHECK-NEXT: addl %eax, %esi 118; CHECK-NEXT: movl %esi, %eax 119; CHECK-NEXT: popl %esi 120; CHECK-NEXT: popl %edi 121; CHECK-NEXT: popl %ebx 122; CHECK-NEXT: retl 123 %resultidiv = sdiv i32 %a, %b 124 %resultdiv = udiv i32 %a, %b 125 %result = add i32 %resultidiv, %resultdiv 126 ret i32 %result 127} 128 129define i32 @Test_use_div_imm_imm() nounwind { 130; CHECK-LABEL: Test_use_div_imm_imm: 131; CHECK: # %bb.0: 132; CHECK-NEXT: movl $64, %eax 133; CHECK-NEXT: retl 134 %resultdiv = sdiv i32 256, 4 135 ret i32 %resultdiv 136} 137 138define i32 @Test_use_div_reg_imm(i32 %a) nounwind { 139; CHECK-LABEL: Test_use_div_reg_imm: 140; CHECK: # %bb.0: 141; CHECK-NEXT: movl $1041204193, %eax # imm = 0x3E0F83E1 142; CHECK-NEXT: imull {{[0-9]+}}(%esp) 143; CHECK-NEXT: movl %edx, %eax 144; CHECK-NEXT: shrl $31, %eax 145; CHECK-NEXT: sarl $3, %edx 146; CHECK-NEXT: leal (%edx,%eax), %eax 147; CHECK-NEXT: retl 148 %resultdiv = sdiv i32 %a, 33 149 ret i32 %resultdiv 150} 151 152define i32 @Test_use_rem_reg_imm(i32 %a) nounwind { 153; CHECK-LABEL: Test_use_rem_reg_imm: 154; CHECK: # %bb.0: 155; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 156; CHECK-NEXT: movl $1041204193, %edx # imm = 0x3E0F83E1 157; CHECK-NEXT: movl %ecx, %eax 158; CHECK-NEXT: imull %edx 159; CHECK-NEXT: movl %edx, %eax 160; CHECK-NEXT: shrl $31, %eax 161; CHECK-NEXT: sarl $3, %edx 162; CHECK-NEXT: addl %eax, %edx 163; CHECK-NEXT: movl %edx, %eax 164; CHECK-NEXT: shll $5, %eax 165; CHECK-NEXT: addl %edx, %eax 166; CHECK-NEXT: subl %eax, %ecx 167; CHECK-NEXT: movl %ecx, %eax 168; CHECK-NEXT: retl 169 %resultrem = srem i32 %a, 33 170 ret i32 %resultrem 171} 172 173define i32 @Test_use_divrem_reg_imm(i32 %a) nounwind { 174; CHECK-LABEL: Test_use_divrem_reg_imm: 175; CHECK: # %bb.0: 176; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 177; CHECK-NEXT: movl $1041204193, %edx # imm = 0x3E0F83E1 178; CHECK-NEXT: movl %ecx, %eax 179; CHECK-NEXT: imull %edx 180; CHECK-NEXT: movl %edx, %eax 181; CHECK-NEXT: shrl $31, %eax 182; CHECK-NEXT: sarl $3, %edx 183; CHECK-NEXT: addl %eax, %edx 184; CHECK-NEXT: movl %edx, %eax 185; CHECK-NEXT: shll $5, %eax 186; CHECK-NEXT: addl %edx, %eax 187; CHECK-NEXT: subl %eax, %ecx 188; CHECK-NEXT: addl %edx, %ecx 189; CHECK-NEXT: movl %ecx, %eax 190; CHECK-NEXT: retl 191 %resultdiv = sdiv i32 %a, 33 192 %resultrem = srem i32 %a, 33 193 %result = add i32 %resultdiv, %resultrem 194 ret i32 %result 195} 196 197define i32 @Test_use_div_imm_reg(i32 %a) nounwind { 198; CHECK-LABEL: Test_use_div_imm_reg: 199; CHECK: # %bb.0: 200; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 201; CHECK-NEXT: testl $-256, %ecx 202; CHECK-NEXT: je .LBB8_1 203; CHECK-NEXT: # %bb.2: 204; CHECK-NEXT: movl $4, %eax 205; CHECK-NEXT: xorl %edx, %edx 206; CHECK-NEXT: idivl %ecx 207; CHECK-NEXT: retl 208; CHECK-NEXT: .LBB8_1: 209; CHECK-NEXT: movb $4, %al 210; CHECK-NEXT: movzbl %al, %eax 211; CHECK-NEXT: # kill: def $eax killed $eax def $ax 212; CHECK-NEXT: divb %cl 213; CHECK-NEXT: movzbl %al, %eax 214; CHECK-NEXT: retl 215 %resultdiv = sdiv i32 4, %a 216 ret i32 %resultdiv 217} 218 219define i32 @Test_use_rem_imm_reg(i32 %a) nounwind { 220; CHECK-LABEL: Test_use_rem_imm_reg: 221; CHECK: # %bb.0: 222; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 223; CHECK-NEXT: testl $-256, %ecx 224; CHECK-NEXT: je .LBB9_1 225; CHECK-NEXT: # %bb.2: 226; CHECK-NEXT: movl $4, %eax 227; CHECK-NEXT: xorl %edx, %edx 228; CHECK-NEXT: idivl %ecx 229; CHECK-NEXT: retl 230; CHECK-NEXT: .LBB9_1: 231; CHECK-NEXT: movb $4, %al 232; CHECK-NEXT: movzbl %al, %eax 233; CHECK-NEXT: # kill: def $eax killed $eax def $ax 234; CHECK-NEXT: divb %cl 235; CHECK-NEXT: movzbl %al, %eax 236; CHECK-NEXT: retl 237 %resultdiv = sdiv i32 4, %a 238 ret i32 %resultdiv 239} 240