This is an automated email from the ASF dual-hosted git repository.

tqchen pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm-tirx.git


The following commit(s) were added to refs/heads/main by this push:
     new dc35fb049 [FIX] Rebuild Ramp types during dtype legalization (#43)
dc35fb049 is described below

commit dc35fb049bc963b98b6ce851aa161073e5ead797
Author: Tianqi Chen <[email protected]>
AuthorDate: Sat Oct 24 14:32:05 2026 -0400

    [FIX] Rebuild Ramp types during dtype legalization (#43)
    
    Rebuild Ramp expressions when unsupported-dtype legalization promotes
    their operands, so the derived vector result type follows the promoted
    base and stride. Preserve lane expressions, source locations, and
    unchanged nodes at the existing legalization boundary.
    
    This prevents a BF16 Ramp from retaining a BF16 vector result after its
    operands become float32, which otherwise reaches LLVM with an
    unsupported vector element type.
---
 src/tirx/transform/unsupported_dtype_legalize.cc  | 15 +++++++++++++++
 tests/python/tirx/transform/test_bf16_legalize.py | 22 ++++++++++++++++++++++
 2 files changed, 37 insertions(+)

diff --git a/src/tirx/transform/unsupported_dtype_legalize.cc 
b/src/tirx/transform/unsupported_dtype_legalize.cc
index c675a5357..af578f7e8 100644
--- a/src/tirx/transform/unsupported_dtype_legalize.cc
+++ b/src/tirx/transform/unsupported_dtype_legalize.cc
@@ -209,6 +209,21 @@ class ComputeLegalizer : public StmtExprMutator {
     }
   }
 
+  UnchangedOr<PrimExpr> Mutate_(const prim::RampObj* op, InplaceMode 
inplace_mode) final {
+    PrimExpr base =
+        PromoteToTarget(this->Mutate(op->base, 
inplace_mode).ValueOrUnchanged(op->base));
+    PrimExpr stride =
+        PromoteToTarget(this->Mutate(op->stride, 
inplace_mode).ValueOrUnchanged(op->stride));
+    auto lanes_result = this->Mutate(op->lanes, inplace_mode);
+    bool lanes_unchanged = lanes_result.UnchangedOrSameAs(op->lanes);
+    PrimExpr lanes = std::move(lanes_result).ValueOrUnchanged(op->lanes);
+    if (base.same_as(op->base) && stride.same_as(op->stride) && 
lanes_unchanged &&
+        !MatchType(op->ty)) {
+      return ffi::Unchanged();
+    }
+    return prim::Ramp(base, stride, lanes, op->loc);
+  }
+
   UnchangedOr<PrimExpr> Mutate_(const prim::BroadcastObj* op, InplaceMode 
inplace_mode) final {
     PrimExpr value =
         PromoteToTarget(this->Mutate(op->value, 
inplace_mode).ValueOrUnchanged(op->value));
diff --git a/tests/python/tirx/transform/test_bf16_legalize.py 
b/tests/python/tirx/transform/test_bf16_legalize.py
index aa42d9c2c..6e8af995d 100644
--- a/tests/python/tirx/transform/test_bf16_legalize.py
+++ b/tests/python/tirx/transform/test_bf16_legalize.py
@@ -47,6 +47,28 @@ def f32tobf16(v):
     return T.reinterpret(f32tou16(v), ty="bfloat16")
 
 
+def test_bf16_ramp_will_legalize():
+    @I.ir_module
+    class Before:
+        @T.function
+        def main():
+            T.evaluate(T.Ramp(T.bfloat16(0), T.bfloat16(1), 2))
+
+    @I.ir_module
+    class Expected:
+        @T.function
+        def main():
+            T.evaluate(T.Ramp(T.float32(0), T.float32(1), 2))
+
+    target = Target("llvm")
+    before = BindTarget(target)(Before)
+    expected = BindTarget(target)(Expected)
+    after_compute = tvm_tirx.tirx.transform.BF16ComputeLegalize()(before)
+    tvm_tirx.ir.assert_structural_equal(after_compute, expected)
+    after_storage = 
tvm_tirx.tirx.transform.BF16StorageLegalize()(after_compute)
+    tvm_tirx.ir.assert_structural_equal(after_storage, expected)
+
+
 def test_bf16_simple_store_will_legalize():
     def get_before():
         @tvm_tirx.script.ir_module

Reply via email to