Skip to content

Commit 5a5f25f

Browse files
committed
Bitcast constant folding across int/float types
Add cross-type bitcast constant folding that reinterprets bit patterns: - Integer → float: Bitcast(IntToExpr(Const N)) → FloatToExpr(FConst f) with 32-bit width guard via ResultWidth, and unconditional for Const64 - Float → integer: Bitcast(FloatToExpr(FConst f)) → IntToExpr(Const n) Four new primitives handle the bit reinterpretation: - bitcast-i32-to-f: lower 32 bits as f32, promoted to f64 - bitcast-i64-to-f: all 64 bits as f64 - bitcast-f-to-i32: f64 demoted to f32, bits as i64 - bitcast-f-to-i64: f64 bits as i64 This matches the C++ BitCastScalarOrVector folding rule.
1 parent fc81bc3 commit 5a5f25f

2 files changed

Lines changed: 48 additions & 2 deletions

File tree

rust/spirv-tools-opt/src/egglog_opt/mod.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,26 @@ fn float_neg_bits(a: i64) -> i64 {
487487
}
488488
}
489489

490+
/// Bitcast 32-bit integer constant to f64 (reinterpret lower 32 bits as f32, promote to f64).
491+
fn bitcast_int_to_float32(v: i64) -> f64 {
492+
f32::from_bits(v as u32) as f64
493+
}
494+
495+
/// Bitcast 64-bit integer constant to f64 (reinterpret bits as f64).
496+
fn bitcast_int_to_float64(v: i64) -> f64 {
497+
f64::from_bits(v as u64)
498+
}
499+
500+
/// Bitcast f64 constant to 32-bit integer (demote to f32, get u32 bits).
501+
fn bitcast_float_to_int32(v: f64) -> i64 {
502+
(v as f32).to_bits() as i64
503+
}
504+
505+
/// Bitcast f64 constant to 64-bit integer (get u64 bits).
506+
fn bitcast_float_to_int64(v: f64) -> i64 {
507+
v.to_bits() as i64
508+
}
509+
490510
/// SConvert constant fold: sign-extend or truncate to target width.
491511
fn sconvert_fold(v: i64, dst_width: i64) -> i64 {
492512
let dw = dst_width as u32;
@@ -908,6 +928,20 @@ pub fn create_spirv_egraph() -> Result<EGraph, EgglogOptError> {
908928
uconvert_fold(v, sw, dw)
909929
});
910930

931+
// Bitcast constant folding primitives (cross int/float reinterpretation)
932+
add_primitive!(&mut egraph, "bitcast-i32-to-f" = |v: i64| -> F {
933+
F::from(OrderedFloat(bitcast_int_to_float32(v)))
934+
});
935+
add_primitive!(&mut egraph, "bitcast-i64-to-f" = |v: i64| -> F {
936+
F::from(OrderedFloat(bitcast_int_to_float64(v)))
937+
});
938+
add_primitive!(&mut egraph, "bitcast-f-to-i32" = |v: F| -> i64 {
939+
bitcast_float_to_int32(v.0.0)
940+
});
941+
add_primitive!(&mut egraph, "bitcast-f-to-i64" = |v: F| -> i64 {
942+
bitcast_float_to_int64(v.0.0)
943+
});
944+
911945
// Now load the base SPIR-V language and rules (which use the primitives above)
912946
egraph
913947
.parse_and_run_program(None, SPIRV_EGGLOG_PROGRAM)

rust/spirv-tools-opt/src/rules/primitives.egg

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -486,13 +486,25 @@
486486
; =============================================================================
487487
; BitCast Constant Folding
488488
; =============================================================================
489-
; Bitcast of a constant preserves the bit pattern (identity).
490-
489+
; Same-sort bitcast preserves the bit pattern (identity).
491490
(rule ((= e (Bitcast (IntToExpr (Const a)))))
492491
((union e (IntToExpr (Const a)))))
493492
(rule ((= e (BitCast (IntToExpr (Const a)))))
494493
((union e (IntToExpr (Const a)))))
495494

495+
; Cross-type bitcast: reinterpret integer bits as float (32-bit)
496+
(rule ((= e (Bitcast (IntToExpr (Const a))))
497+
(= 32 (ResultWidth (Const a))))
498+
((union e (FloatToExpr (FConst (bitcast-i32-to-f a))))))
499+
500+
; Cross-type bitcast: reinterpret integer bits as float (64-bit)
501+
(rule ((= e (Bitcast (IntToExpr (Const64 a)))))
502+
((union e (FloatToExpr (FConst (bitcast-i64-to-f a))))))
503+
504+
; Cross-type bitcast: reinterpret float bits as integer (32-bit)
505+
(rule ((= e (Bitcast (FloatToExpr (FConst a)))))
506+
((union e (IntToExpr (Const (bitcast-f-to-i32 a))))))
507+
496508
; =============================================================================
497509
; SConvert/UConvert Constant Folding
498510
; =============================================================================

0 commit comments

Comments
 (0)