[llvm] [InstCombine] Split div/rem by a select of constants with a variable dividend (PR #216908)
Adam Scott via llvm-commits
llvm-commits at lists.llvm.org
Sun Aug 23 21:11:08 PDT 2026
================
@@ -518,5 +518,85 @@ define <2 x i64> @sdivrem_identity_const(<2 x i1> %c, <2 x i64> %x) {
%r = add <2 x i64> %div, %rem
ret <2 x i64> %r
}
-;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; CHECK-X64: {{.*}}
+
+define i32 @sdiv_select_of_constants(i32 %x, i1 %c) {
+; CHECK-X64-LABEL: sdiv_select_of_constants:
+; CHECK-X64: # %bb.0:
+; CHECK-X64-NEXT: # kill: def $edi killed $edi def $rdi
+; CHECK-X64-NEXT: leal 3(%rdi), %ecx
+; CHECK-X64-NEXT: testl %edi, %edi
+; CHECK-X64-NEXT: cmovnsl %edi, %ecx
+; CHECK-X64-NEXT: sarl $2, %ecx
+; CHECK-X64-NEXT: movslq %edi, %rax
+; CHECK-X64-NEXT: imulq $1717986919, %rax, %rax # imm = 0x66666667
+; CHECK-X64-NEXT: movq %rax, %rdx
+; CHECK-X64-NEXT: shrq $63, %rdx
+; CHECK-X64-NEXT: sarq $33, %rax
+; CHECK-X64-NEXT: addl %edx, %eax
+; CHECK-X64-NEXT: testb $1, %sil
+; CHECK-X64-NEXT: cmovnel %ecx, %eax
+; CHECK-X64-NEXT: # kill: def $eax killed $eax killed $rax
+; CHECK-X64-NEXT: retq
+ %a = sdiv i32 %x, 4
+ %b = sdiv i32 %x, 5
+ %r = select i1 %c, i32 %a, i32 %b
+ ret i32 %r
+}
+
+define i32 @urem_select_of_constants(i32 %x, i1 %c) {
+; CHECK-X64-V3-LABEL: urem_select_of_constants:
+; CHECK-X64-V3: # %bb.0:
+; CHECK-X64-V3-NEXT: movl %edi, %eax
+; CHECK-X64-V3-NEXT: movl %edi, %edx
+; CHECK-X64-V3-NEXT: movl $2863311531, %ecx # imm = 0xAAAAAAAB
+; CHECK-X64-V3-NEXT: imulq %rdx, %rcx
+; CHECK-X64-V3-NEXT: shrq $34, %rcx
+; CHECK-X64-V3-NEXT: addl %ecx, %ecx
+; CHECK-X64-V3-NEXT: leal (%rcx,%rcx,2), %ecx
+; CHECK-X64-V3-NEXT: movabsq $2635249153617166336, %rdi # imm = 0x24924924A0000000
+; CHECK-X64-V3-NEXT: mulxq %rdi, %rdx, %rdx
+; CHECK-X64-V3-NEXT: leal (,%rdx,8), %edi
+; CHECK-X64-V3-NEXT: subl %edx, %edi
+; CHECK-X64-V3-NEXT: testb $1, %sil
+; CHECK-X64-V3-NEXT: cmovnel %ecx, %edi
+; CHECK-X64-V3-NEXT: subl %edi, %eax
+; CHECK-X64-V3-NEXT: retq
+;
+; CHECK-X64-V4-LABEL: urem_select_of_constants:
----------------
as4230 wrote:
With `uint16_t a / (12 + b)` it seems the branchless split that this PR does still wins by RT of 2.0 instead of 3.0 https://godbolt.org/z/d689b5c65 .
The already vector cases go the other way though as you already figured in the newer issue you made: https://github.com/llvm/llvm-project/issues/217613
https://github.com/llvm/llvm-project/pull/216908
More information about the llvm-commits
mailing list