Skip to content

Modulo operation fails on integers of bitwidth greater than 128 bits #1534

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
kristate opened this issue Sep 17, 2018 · 7 comments
Open

Modulo operation fails on integers of bitwidth greater than 128 bits #1534

kristate opened this issue Sep 17, 2018 · 7 comments
Labels
contributor friendly This issue is limited in scope and/or knowledge of Zig internals.
Milestone

Comments

@kristate
Copy link
Contributor

test "mod129" {
    const base = 10;
    var a: @IntType(false, 129) = 0;
    const digit = a % base;
}

results in compiler error:

LLVM ERROR: Unsupported library call operation!

#1533 is related.

@kristate
Copy link
Contributor Author

backtrace:

(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.3
  * frame #0: 0x0000000102474cba zig`llvm::report_fatal_error(char const*, bool)
    frame #1: 0x0000000101bb5f95 zig`llvm::TargetLowering::makeLibCall(llvm::SelectionDAG&, llvm::RTLIB::Libcall, llvm::EVT, llvm::ArrayRef<llvm::SDValue>, bool, llvm::SDLoc const&, bool, bool) const + 1445
    frame #2: 0x0000000101afba28 zig`llvm::DAGTypeLegalizer::ExpandIntRes_UREM(llvm::SDNode*, llvm::SDValue&, llvm::SDValue&) + 400
    frame #3: 0x0000000101af6dd8 zig`llvm::DAGTypeLegalizer::ExpandIntegerResult(llvm::SDNode*, unsigned int) + 1524
    frame #4: 0x0000000101b072e5 zig`llvm::DAGTypeLegalizer::run() + 963
    frame #5: 0x0000000101b0a853 zig`llvm::SelectionDAG::LegalizeTypes() + 55
    frame #6: 0x0000000101ba6140 zig`llvm::SelectionDAGISel::CodeGenAndEmitDAG() + 354
    frame #7: 0x0000000101ba53e2 zig`llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) + 5390
    frame #8: 0x0000000101ba364e zig`llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) + 1512
    frame #9: 0x000000010193e6f8 zig`(anonymous namespace)::X86DAGToDAGISel::runOnMachineFunction(llvm::MachineFunction&) + 20
    frame #10: 0x0000000101d0ad8f zig`llvm::MachineFunctionPass::runOnFunction(llvm::Function&) + 113
    frame #11: 0x00000001023f71a4 zig`llvm::FPPassManager::runOnFunction(llvm::Function&) + 276
    frame #12: 0x00000001023f7369 zig`llvm::FPPassManager::runOnModule(llvm::Module&) + 49
    frame #13: 0x00000001023f7695 zig`llvm::legacy::PassManagerImpl::run(llvm::Module&) + 579
    frame #14: 0x00000001001059c5 zig`::ZigLLVMTargetMachineEmitToFile(targ_machine_ref=0x0000000105418c70, module_ref=0x00000001054173e0, filename="zig-cache/test.o", output_type=ZigLLVM_EmitBinary, error_message=0x00007ffeefbfefd0, is_debug=true, is_small=false, time_report=false) at zig_llvm.cpp:181
    frame #15: 0x000000010003a608 zig`zig_llvm_emit_output(g=0x000000010580c600) at codegen.cpp:6408
    frame #16: 0x0000000100037cb3 zig`codegen_build_and_link(g=0x000000010580c600) at codegen.cpp:8231
    frame #17: 0x00000001000cf2d1 zig`main(argc=3, argv=0x00007ffeefbff8d8) at main.cpp:978
    frame #18: 0x00007fff5b6e1015 libdyld.dylib`start + 1
    frame #19: 0x00007fff5b6e1015 libdyld.dylib`start + 1

@kristate
Copy link
Contributor Author

Hmm, llvm does not support urem and friends on integers with bitwidth > 128:

urem_test.ll:

define i256 @urem_test(i256 %a) {
  %1 = urem i256 %a, %a
  ret i256 %1
}

llc urem_test.ll -march=x86-64 -o urem_test-x86-64.s returns:

LLVM ERROR: Unsupported library call operation!

@ghost
Copy link

ghost commented Sep 17, 2018

very similar to #1485

@andrewrk andrewrk added this to the 0.4.0 milestone Sep 17, 2018
@andrewrk
Copy link
Member

The short answer to this and #1485 is that we need to send a patch to LLVM to make it emit library calls for this even though the scope of those library calls is outside of the standardized compiler-rt.

@andrewrk andrewrk added contributor friendly This issue is limited in scope and/or knowledge of Zig internals. upstream An issue with a third party project that Zig uses. labels Sep 17, 2018
@kristate kristate changed the title modulus operation fails on integers of bitwidth greater than 128 bits Modulo operation fails on integers of bitwidth greater than 128 bits Sep 17, 2018
@andrewrk andrewrk modified the milestones: 0.4.0, 0.5.0 Sep 28, 2018
@andrewrk andrewrk modified the milestones: 0.5.0, 0.6.0 Apr 11, 2019
@andrewrk andrewrk modified the milestones: 0.6.0, 0.7.0 Dec 9, 2019
@andrewrk andrewrk modified the milestones: 0.7.0, 0.8.0 Oct 10, 2020
@andrewrk andrewrk modified the milestones: 0.8.0, 0.9.0 Nov 6, 2020
@rtfeldman
Copy link

I also ran into this when trying to compare two i256s for equality - got the LLVM ERROR: Unsupported library call operation! but saw an actual segfault when trying to do multiplication.

To reproduce:

const std = @import("std");

fn square(num: i128) i128 {
    return @intCast(i128, @intCast(i256, num) * @intCast(i256, num));
}

test "square" {
    std.testing.expectEqual(square(5), 25);
}

produces this output, when run with zig test:

LLVM Emit Output... [1]    14190 segmentation fault  zig test repro.zig

@Vexu
Copy link
Member

Vexu commented Oct 24, 2022

LLVM15 lowers division, remainder and modulus to __udivei4, __umodei4, __divei4 and __modei4.

https://discourse.llvm.org/t/rfc-add-support-for-division-of-large-bitint-builtins-selectiondag-globalisel-clang/60329

@Vexu Vexu removed the upstream An issue with a third party project that Zig uses. label Oct 24, 2022
@jedisct1
Copy link
Contributor

jedisct1 commented Nov 2, 2022

929cb68 implements __udivei4 and __umodei4, allowing > 128 bit integers to be formatted.

But looks like another direction is being taken by LLVM.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
contributor friendly This issue is limited in scope and/or knowledge of Zig internals.
Projects
None yet
Development

No branches or pull requests

5 participants