Skip to content

ONNX Runtime CPU BitShift incorrectly handles uint64 shift amount == 64 #28262

Description

@ALinrunrun

Describe the issue

ONNX Runtime CPUExecutionProvider produces an incorrect result for ONNX BitShift when the input type is uint64 and the shift amount is 64.

In a minimal model with a single BitShift node using direction="RIGHT", shifting [1000, 255, 1, 42] by [64, 64, 64, 64] returns the original input values instead of [0, 0, 0, 0].

This behavior is consistent with native 64-bit shift masking on x86, where a shift amount of 64 may effectively behave like 0. The issue reproduces with CPUExecutionProvider and ORT_DISABLE_ALL. With ORT_ENABLE_ALL, this constant-input case may be hidden by constant folding.

To reproduce

import numpy as np
import onnx
from onnx import TensorProto, helper
import onnxruntime as ort

vals = np.array([[1000, 255, 1, 42]], dtype=np.uint64)
shifts = np.array([[64, 64, 64, 64]], dtype=np.uint64)
expected = np.zeros_like(vals)

X = helper.make_tensor_value_info("x", TensorProto.UINT64, list(vals.shape))
N = helper.make_tensor_value_info("n", TensorProto.UINT64, list(shifts.shape))
Y = helper.make_tensor_value_info("y", TensorProto.UINT64, list(vals.shape))

node = helper.make_node("BitShift", ["x", "n"], ["y"], direction="RIGHT")
graph = helper.make_graph([node], "bitshift64", [X, N], [Y])
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 11)])
model.ir_version = 8
onnx.checker.check_model(model)

feed = {"x": vals, "n": shifts}

so = ort.SessionOptions()
so.graph_optimization_level = ort.GraphOptimizationLevel.ORT_DISABLE_ALL

sess = ort.InferenceSession(
    model.SerializeToString(),
    sess_options=so,
    providers=["CPUExecutionProvider"],
)

out = sess.run(None, feed)[0]

print(f"Input values: {vals[0].tolist()}")
print(f"Shift amount: {shifts[0].tolist()}")
print(f"Expected:     {expected[0].tolist()}")
print(f"ORT output:   {out[0].tolist()}")

PASS = np.array_equal(out, expected)
print(f"PASS={PASS}")

Urgency

Expected output

Input values: [1000, 255, 1, 42]
Shift amount: [64, 64, 64, 64]
Expected:     [0, 0, 0, 0]
ORT output:   [0, 0, 0, 0]
PASS=True

Actual output

Input values: [1000, 255, 1, 42]
Shift amount: [64, 64, 64, 64]
Expected:     [0, 0, 0, 0]
ORT output:   [1000, 255, 1, 42]
PASS=False

Platform

Linux

OS Version

Linux-6.17.0-20-generic-x86_64-with-glibc2.39

ONNX Runtime Installation

Released Package

ONNX Runtime Version or Commit ID

1.25.1

ONNX Runtime API

Python

Architecture

X86

Execution Provider

Default CPU

Execution Provider Library Version

No response

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions