385 lines · plain
1; Check that 64-bit division is bypassed correctly.2; RUN: llc < %s -mtriple=x86_64-- -mattr=-idivq-to-divl | FileCheck %s --check-prefixes=CHECK,FAST-DIVQ3; RUN: llc < %s -mtriple=x86_64-- -mattr=+idivq-to-divl | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ4; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64 | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ5; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64-v2 | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ6; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64-v3 | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ7; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64-v4 | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ8; Intel9; RUN: llc < %s -mtriple=x86_64-- -mcpu=nehalem | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ10; RUN: llc < %s -mtriple=x86_64-- -mcpu=sandybridge | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ11; RUN: llc < %s -mtriple=x86_64-- -mcpu=haswell | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ12; RUN: llc < %s -mtriple=x86_64-- -mcpu=skylake | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ13; RUN: llc < %s -mtriple=x86_64-- -mcpu=alderlake | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ14; AMD15; RUN: llc < %s -mtriple=x86_64-- -mcpu=barcelona | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ16; RUN: llc < %s -mtriple=x86_64-- -mcpu=btver1 | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ17; RUN: llc < %s -mtriple=x86_64-- -mcpu=btver2 | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ18; RUN: llc < %s -mtriple=x86_64-- -mcpu=bdver1 | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ19; RUN: llc < %s -mtriple=x86_64-- -mcpu=bdver2 | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ20; RUN: llc < %s -mtriple=x86_64-- -mcpu=bdver3 | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ21; RUN: llc < %s -mtriple=x86_64-- -mcpu=bdver4 | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ22; RUN: llc < %s -mtriple=x86_64-- -mcpu=znver1 | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ23; RUN: llc < %s -mtriple=x86_64-- -mcpu=znver2 | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ24; RUN: llc < %s -mtriple=x86_64-- -mcpu=znver3 | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ25; RUN: llc < %s -mtriple=x86_64-- -mcpu=znver4 | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ26; RUN: llc < %s -mtriple=x86_64-- -mcpu=znver5 | FileCheck %s --check-prefixes=CHECK,SLOW-DIVQ27 28; Additional tests for 64-bit divide bypass29 30;31; SDIV32;33 34define i64 @sdiv_quotient(i64 %a, i64 %b) nounwind {35; FAST-DIVQ-LABEL: sdiv_quotient:36; FAST-DIVQ: # %bb.0:37; FAST-DIVQ-NEXT: movq %rdi, %rax38; FAST-DIVQ-NEXT: cqto39; FAST-DIVQ-NEXT: idivq %rsi40; FAST-DIVQ-NEXT: retq41;42; SLOW-DIVQ-LABEL: sdiv_quotient:43; SLOW-DIVQ: # %bb.0:44; SLOW-DIVQ-DAG: movq %rdi, %rax45; SLOW-DIVQ-DAG: movq %rdi, %rcx46; SLOW-DIVQ-DAG: orq %rsi, %rcx47; SLOW-DIVQ-DAG: shrq $32, %rcx48; SLOW-DIVQ-NEXT: je .LBB0_149; SLOW-DIVQ-NEXT: # %bb.2:50; SLOW-DIVQ-NEXT: cqto51; SLOW-DIVQ-NEXT: idivq %rsi52; SLOW-DIVQ-NEXT: retq53; SLOW-DIVQ-NEXT: .LBB0_1:54; SLOW-DIVQ-DAG: # kill: def $eax killed $eax killed $rax55; SLOW-DIVQ-DAG: xorl %edx, %edx56; SLOW-DIVQ-NEXT: divl %esi57; SLOW-DIVQ-NEXT: # kill: def $eax killed $eax def $rax58; SLOW-DIVQ-NEXT: retq59 %result = sdiv i64 %a, %b60 ret i64 %result61}62 63define i64 @sdiv_quotient_optsize(i64 %a, i64 %b) nounwind optsize {64; CHECK-LABEL: sdiv_quotient_optsize:65; CHECK: # %bb.0:66; CHECK-NEXT: movq %rdi, %rax67; CHECK-NEXT: cqto68; CHECK-NEXT: idivq %rsi69; CHECK-NEXT: retq70 %result = sdiv i64 %a, %b71 ret i64 %result72}73 74define i64 @sdiv_quotient_minsize(i64 %a, i64 %b) nounwind minsize {75; CHECK-LABEL: sdiv_quotient_minsize:76; CHECK: # %bb.0:77; CHECK-NEXT: movq %rdi, %rax78; CHECK-NEXT: cqto79; CHECK-NEXT: idivq %rsi80; CHECK-NEXT: retq81 %result = sdiv i64 %a, %b82 ret i64 %result83}84 85define i64 @sdiv_remainder(i64 %a, i64 %b) nounwind {86; FAST-DIVQ-LABEL: sdiv_remainder:87; FAST-DIVQ: # %bb.0:88; FAST-DIVQ-NEXT: movq %rdi, %rax89; FAST-DIVQ-NEXT: cqto90; FAST-DIVQ-NEXT: idivq %rsi91; FAST-DIVQ-NEXT: movq %rdx, %rax92; FAST-DIVQ-NEXT: retq93;94; SLOW-DIVQ-LABEL: sdiv_remainder:95; SLOW-DIVQ: # %bb.0:96; SLOW-DIVQ-DAG: movq %rdi, %rax97; SLOW-DIVQ-DAG: movq %rdi, %rcx98; SLOW-DIVQ-DAG: orq %rsi, %rcx99; SLOW-DIVQ-DAG: shrq $32, %rcx100; SLOW-DIVQ-NEXT: je .LBB3_1101; SLOW-DIVQ-NEXT: # %bb.2:102; SLOW-DIVQ-NEXT: cqto103; SLOW-DIVQ-NEXT: idivq %rsi104; SLOW-DIVQ-NEXT: movq %rdx, %rax105; SLOW-DIVQ-NEXT: retq106; SLOW-DIVQ-NEXT: .LBB3_1:107; SLOW-DIVQ-DAG: # kill: def $eax killed $eax killed $rax108; SLOW-DIVQ-DAG: xorl %edx, %edx109; SLOW-DIVQ-NEXT: divl %esi110; SLOW-DIVQ-NEXT: movl %edx, %eax111; SLOW-DIVQ-NEXT: retq112 %result = srem i64 %a, %b113 ret i64 %result114}115 116define i64 @sdiv_remainder_optsize(i64 %a, i64 %b) nounwind optsize {117; CHECK-LABEL: sdiv_remainder_optsize:118; CHECK: # %bb.0:119; CHECK-NEXT: movq %rdi, %rax120; CHECK-NEXT: cqto121; CHECK-NEXT: idivq %rsi122; CHECK-NEXT: movq %rdx, %rax123; CHECK-NEXT: retq124 %result = srem i64 %a, %b125 ret i64 %result126}127 128define i64 @sdiv_remainder_minsize(i64 %a, i64 %b) nounwind minsize {129; CHECK-LABEL: sdiv_remainder_minsize:130; CHECK: # %bb.0:131; CHECK-NEXT: movq %rdi, %rax132; CHECK-NEXT: cqto133; CHECK-NEXT: idivq %rsi134; CHECK-NEXT: movq %rdx, %rax135; CHECK-NEXT: retq136 %result = srem i64 %a, %b137 ret i64 %result138}139 140define i64 @sdiv_quotient_and_remainder(i64 %a, i64 %b) nounwind {141; FAST-DIVQ-LABEL: sdiv_quotient_and_remainder:142; FAST-DIVQ: # %bb.0:143; FAST-DIVQ-NEXT: movq %rdi, %rax144; FAST-DIVQ-NEXT: cqto145; FAST-DIVQ-NEXT: idivq %rsi146; FAST-DIVQ-NEXT: addq %rdx, %rax147; FAST-DIVQ-NEXT: retq148;149; SLOW-DIVQ-LABEL: sdiv_quotient_and_remainder:150; SLOW-DIVQ: # %bb.0:151; SLOW-DIVQ-DAG: movq %rdi, %rax152; SLOW-DIVQ-DAG: movq %rdi, %rcx153; SLOW-DIVQ-DAG: orq %rsi, %rcx154; SLOW-DIVQ-DAG: shrq $32, %rcx155; SLOW-DIVQ-NEXT: je .LBB6_1156; SLOW-DIVQ-NEXT: # %bb.2:157; SLOW-DIVQ-NEXT: cqto158; SLOW-DIVQ-NEXT: idivq %rsi159; SLOW-DIVQ-NEXT: addq %rdx, %rax160; SLOW-DIVQ-NEXT: retq161; SLOW-DIVQ-NEXT: .LBB6_1:162; SLOW-DIVQ-DAG: # kill: def $eax killed $eax killed $rax163; SLOW-DIVQ-DAG: xorl %edx, %edx164; SLOW-DIVQ-NEXT: divl %esi165; SLOW-DIVQ-NEXT: # kill: def $edx killed $edx def $rdx166; SLOW-DIVQ-NEXT: # kill: def $eax killed $eax def $rax167; SLOW-DIVQ-NEXT: addq %rdx, %rax168; SLOW-DIVQ-NEXT: retq169 %resultdiv = sdiv i64 %a, %b170 %resultrem = srem i64 %a, %b171 %result = add i64 %resultdiv, %resultrem172 ret i64 %result173}174 175define i64 @sdiv_quotient_and_remainder_optsize(i64 %a, i64 %b) nounwind optsize {176; CHECK-LABEL: sdiv_quotient_and_remainder_optsize:177; CHECK: # %bb.0:178; CHECK-NEXT: movq %rdi, %rax179; CHECK-NEXT: cqto180; CHECK-NEXT: idivq %rsi181; CHECK-NEXT: addq %rdx, %rax182; CHECK-NEXT: retq183 %resultdiv = sdiv i64 %a, %b184 %resultrem = srem i64 %a, %b185 %result = add i64 %resultdiv, %resultrem186 ret i64 %result187}188 189define i64 @sdiv_quotient_and_remainder_minsize(i64 %a, i64 %b) nounwind minsize {190; CHECK-LABEL: sdiv_quotient_and_remainder_minsize:191; CHECK: # %bb.0:192; CHECK-NEXT: movq %rdi, %rax193; CHECK-NEXT: cqto194; CHECK-NEXT: idivq %rsi195; CHECK-NEXT: addq %rdx, %rax196; CHECK-NEXT: retq197 %resultdiv = sdiv i64 %a, %b198 %resultrem = srem i64 %a, %b199 %result = add i64 %resultdiv, %resultrem200 ret i64 %result201}202 203;204; UDIV205;206 207define i64 @udiv_quotient(i64 %a, i64 %b) nounwind {208; FAST-DIVQ-LABEL: udiv_quotient:209; FAST-DIVQ: # %bb.0:210; FAST-DIVQ-NEXT: movq %rdi, %rax211; FAST-DIVQ-NEXT: xorl %edx, %edx212; FAST-DIVQ-NEXT: divq %rsi213; FAST-DIVQ-NEXT: retq214;215; SLOW-DIVQ-LABEL: udiv_quotient:216; SLOW-DIVQ: # %bb.0:217; SLOW-DIVQ-DAG: movq %rdi, %rax218; SLOW-DIVQ-DAG: movq %rdi, %rcx219; SLOW-DIVQ-DAG: orq %rsi, %rcx220; SLOW-DIVQ-DAG: shrq $32, %rcx221; SLOW-DIVQ-NEXT: je .LBB9_1222; SLOW-DIVQ-NEXT: # %bb.2:223; SLOW-DIVQ-NEXT: xorl %edx, %edx224; SLOW-DIVQ-NEXT: divq %rsi225; SLOW-DIVQ-NEXT: retq226; SLOW-DIVQ-NEXT: .LBB9_1:227; SLOW-DIVQ-DAG: # kill: def $eax killed $eax killed $rax228; SLOW-DIVQ-DAG: xorl %edx, %edx229; SLOW-DIVQ-NEXT: divl %esi230; SLOW-DIVQ-NEXT: # kill: def $eax killed $eax def $rax231; SLOW-DIVQ-NEXT: retq232 %result = udiv i64 %a, %b233 ret i64 %result234}235 236define i64 @udiv_quotient_optsize(i64 %a, i64 %b) nounwind optsize {237; CHECK-LABEL: udiv_quotient_optsize:238; CHECK: # %bb.0:239; CHECK-NEXT: movq %rdi, %rax240; CHECK-NEXT: xorl %edx, %edx241; CHECK-NEXT: divq %rsi242; CHECK-NEXT: retq243 %result = udiv i64 %a, %b244 ret i64 %result245}246 247define i64 @udiv_quotient_minsize(i64 %a, i64 %b) nounwind minsize {248; CHECK-LABEL: udiv_quotient_minsize:249; CHECK: # %bb.0:250; CHECK-NEXT: movq %rdi, %rax251; CHECK-NEXT: xorl %edx, %edx252; CHECK-NEXT: divq %rsi253; CHECK-NEXT: retq254 %result = udiv i64 %a, %b255 ret i64 %result256}257 258define i64 @udiv_remainder(i64 %a, i64 %b) nounwind {259; FAST-DIVQ-LABEL: udiv_remainder:260; FAST-DIVQ: # %bb.0:261; FAST-DIVQ-NEXT: movq %rdi, %rax262; FAST-DIVQ-NEXT: xorl %edx, %edx263; FAST-DIVQ-NEXT: divq %rsi264; FAST-DIVQ-NEXT: movq %rdx, %rax265; FAST-DIVQ-NEXT: retq266;267; SLOW-DIVQ-LABEL: udiv_remainder:268; SLOW-DIVQ: # %bb.0:269; SLOW-DIVQ-DAG: movq %rdi, %rax270; SLOW-DIVQ-DAG: movq %rdi, %rcx271; SLOW-DIVQ-DAG: orq %rsi, %rcx272; SLOW-DIVQ-DAG: shrq $32, %rcx273; SLOW-DIVQ-NEXT: je .LBB12_1274; SLOW-DIVQ-NEXT: # %bb.2:275; SLOW-DIVQ-NEXT: xorl %edx, %edx276; SLOW-DIVQ-NEXT: divq %rsi277; SLOW-DIVQ-NEXT: movq %rdx, %rax278; SLOW-DIVQ-NEXT: retq279; SLOW-DIVQ-NEXT: .LBB12_1:280; SLOW-DIVQ-DAG: # kill: def $eax killed $eax killed $rax281; SLOW-DIVQ-DAG: xorl %edx, %edx282; SLOW-DIVQ-NEXT: divl %esi283; SLOW-DIVQ-NEXT: movl %edx, %eax284; SLOW-DIVQ-NEXT: retq285 %result = urem i64 %a, %b286 ret i64 %result287}288 289define i64 @udiv_remainder_optsize(i64 %a, i64 %b) nounwind optsize {290; CHECK-LABEL: udiv_remainder_optsize:291; CHECK: # %bb.0:292; CHECK-NEXT: movq %rdi, %rax293; CHECK-NEXT: xorl %edx, %edx294; CHECK-NEXT: divq %rsi295; CHECK-NEXT: movq %rdx, %rax296; CHECK-NEXT: retq297 %result = urem i64 %a, %b298 ret i64 %result299}300 301define i64 @udiv_remainder_minsize(i64 %a, i64 %b) nounwind minsize {302; CHECK-LABEL: udiv_remainder_minsize:303; CHECK: # %bb.0:304; CHECK-NEXT: movq %rdi, %rax305; CHECK-NEXT: xorl %edx, %edx306; CHECK-NEXT: divq %rsi307; CHECK-NEXT: movq %rdx, %rax308; CHECK-NEXT: retq309 %result = urem i64 %a, %b310 ret i64 %result311}312 313define i64 @udiv_quotient_and_remainder(i64 %a, i64 %b) nounwind {314; FAST-DIVQ-LABEL: udiv_quotient_and_remainder:315; FAST-DIVQ: # %bb.0:316; FAST-DIVQ-NEXT: movq %rdi, %rax317; FAST-DIVQ-NEXT: xorl %edx, %edx318; FAST-DIVQ-NEXT: divq %rsi319; FAST-DIVQ-NEXT: addq %rdx, %rax320; FAST-DIVQ-NEXT: retq321;322; SLOW-DIVQ-LABEL: udiv_quotient_and_remainder:323; SLOW-DIVQ: # %bb.0:324; SLOW-DIVQ-DAG: movq %rdi, %rax325; SLOW-DIVQ-DAG: movq %rdi, %rcx326; SLOW-DIVQ-DAG: orq %rsi, %rcx327; SLOW-DIVQ-DAG: shrq $32, %rcx328; SLOW-DIVQ-NEXT: je .LBB15_1329; SLOW-DIVQ-NEXT: # %bb.2:330; SLOW-DIVQ-NEXT: xorl %edx, %edx331; SLOW-DIVQ-NEXT: divq %rsi332; SLOW-DIVQ-NEXT: addq %rdx, %rax333; SLOW-DIVQ-NEXT: retq334; SLOW-DIVQ-NEXT: .LBB15_1:335; SLOW-DIVQ-DAG: # kill: def $eax killed $eax killed $rax336; SLOW-DIVQ-DAG: xorl %edx, %edx337; SLOW-DIVQ-NEXT: divl %esi338; SLOW-DIVQ-NEXT: # kill: def $edx killed $edx def $rdx339; SLOW-DIVQ-NEXT: # kill: def $eax killed $eax def $rax340; SLOW-DIVQ-NEXT: addq %rdx, %rax341; SLOW-DIVQ-NEXT: retq342 %resultdiv = udiv i64 %a, %b343 %resultrem = urem i64 %a, %b344 %result = add i64 %resultdiv, %resultrem345 ret i64 %result346}347 348define i64 @udiv_quotient_and_remainder_optsize(i64 %a, i64 %b) nounwind optsize {349; CHECK-LABEL: udiv_quotient_and_remainder_optsize:350; CHECK: # %bb.0:351; CHECK-NEXT: movq %rdi, %rax352; CHECK-NEXT: xorl %edx, %edx353; CHECK-NEXT: divq %rsi354; CHECK-NEXT: addq %rdx, %rax355; CHECK-NEXT: retq356 %resultdiv = udiv i64 %a, %b357 %resultrem = urem i64 %a, %b358 %result = add i64 %resultdiv, %resultrem359 ret i64 %result360}361 362define i64 @udiv_quotient_and_remainder_minsize(i64 %a, i64 %b) nounwind minsize {363; CHECK-LABEL: udiv_quotient_and_remainder_minsize:364; CHECK: # %bb.0:365; CHECK-NEXT: movq %rdi, %rax366; CHECK-NEXT: xorl %edx, %edx367; CHECK-NEXT: divq %rsi368; CHECK-NEXT: addq %rdx, %rax369; CHECK-NEXT: retq370 %resultdiv = udiv i64 %a, %b371 %resultrem = urem i64 %a, %b372 %result = add i64 %resultdiv, %resultrem373 ret i64 %result374}375 376define void @PR43514(i32 %x, i32 %y) {377; CHECK-LABEL: PR43514:378; CHECK: # %bb.0:379; CHECK-NEXT: retq380 %z1 = zext i32 %x to i64381 %z2 = zext i32 %y to i64382 %s = srem i64 %z1, %z2383 ret void384}385