[CodeGen] Always expand division larger than i128
authorNikita Popov <npopov@redhat.com>
Mon, 27 Feb 2023 14:23:01 +0000 (15:23 +0100)
committerNikita Popov <npopov@redhat.com>
Wed, 1 Mar 2023 14:33:45 +0000 (15:33 +0100)
Default MaxDivRemBitWidthSupported to 128, so that divisions larger
than 128 bits are always expanded, without requiring additional
configuration from the target.

Note that this may still emit calls to __udivti3 on 32-bit targets,
which likely don't have an implementation of that builtin. However,
I believe this is sufficient to fix
https://github.com/llvm/llvm-project/issues/60531, because Zig must
already be defining those builtins.

Differential Revision: https://reviews.llvm.org/D144871

llvm/lib/CodeGen/TargetLoweringBase.cpp
llvm/test/CodeGen/Mips/idiv_large.ll [new file with mode: 0644]
llvm/test/CodeGen/PowerPC/idiv_large.ll [new file with mode: 0644]
llvm/test/CodeGen/RISCV/idiv_large.ll [new file with mode: 0644]

index 1ff8840..ac27168 100644 (file)
@@ -724,7 +724,9 @@ TargetLoweringBase::TargetLoweringBase(const TargetMachine &tm) : TM(tm) {
   // with the Target-specific changes necessary.
   MaxAtomicSizeInBitsSupported = 1024;
 
-  MaxDivRemBitWidthSupported = llvm::IntegerType::MAX_INT_BITS;
+  // Assume that even with libcalls, no target supports wider than 128 bit
+  // division.
+  MaxDivRemBitWidthSupported = 128;
 
   MaxLargeFPConvertBitWidthSupported = llvm::IntegerType::MAX_INT_BITS;
 
diff --git a/llvm/test/CodeGen/Mips/idiv_large.ll b/llvm/test/CodeGen/Mips/idiv_large.ll
new file mode 100644 (file)
index 0000000..ffd263f
--- /dev/null
@@ -0,0 +1,17 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=mips-- < %s | FileCheck %s
+; RUN: llc -mtriple=mips64-- < %s | FileCheck %s
+
+define i128 @udiv_i128(i128 %x, i128 %y) nounwind {
+; CHECK-LABEL: udiv_i128:
+; CHECK:    jal __udivti3
+  %res = udiv i128 %x, %y
+  ret i128 %res
+}
+
+define i129 @udiv_i129(i129 %x, i129 %y) nounwind {
+; CHECK-LABEL: udiv_i129:
+; CHECK-NOT: jal
+  %res = udiv i129 %x, %y
+  ret i129 %res
+}
diff --git a/llvm/test/CodeGen/PowerPC/idiv_large.ll b/llvm/test/CodeGen/PowerPC/idiv_large.ll
new file mode 100644 (file)
index 0000000..476aaa5
--- /dev/null
@@ -0,0 +1,17 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=powerpc-- < %s | FileCheck %s
+; RUN: llc -mtriple=powerpc64-- < %s | FileCheck %s
+
+define i128 @udiv_i128(i128 %x, i128 %y) nounwind {
+; CHECK-LABEL: udiv_i128:
+; CHECK:    bl __udivti3
+  %res = udiv i128 %x, %y
+  ret i128 %res
+}
+
+define i129 @udiv_i129(i129 %x, i129 %y) nounwind {
+; CHECK-LABEL: udiv_i129:
+; CHECK-NOT: bl __
+  %res = udiv i129 %x, %y
+  ret i129 %res
+}
diff --git a/llvm/test/CodeGen/RISCV/idiv_large.ll b/llvm/test/CodeGen/RISCV/idiv_large.ll
new file mode 100644 (file)
index 0000000..fb7e4a4
--- /dev/null
@@ -0,0 +1,17 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=riscv32 < %s | FileCheck %s
+; RUN: llc -mtriple=riscv64 < %s | FileCheck %s
+
+define i128 @udiv_i128(i128 %x, i128 %y) nounwind {
+; CHECK-LABEL: udiv_i128:
+; CHECK:    call __udivti3
+  %res = udiv i128 %x, %y
+  ret i128 %res
+}
+
+define i129 @udiv_i129(i129 %x, i129 %y) nounwind {
+; CHECK-LABEL: udiv_i129:
+; CHECK-NOT: call{{.*}}div
+  %res = udiv i129 %x, %y
+  ret i129 %res
+}