Skip to content

better const folding for int and bool #317

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
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
592 changes: 442 additions & 150 deletions crates/rustc_codegen_spirv/src/builder/builder_methods.rs

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions crates/rustc_codegen_spirv/src/builder/libm_intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,20 +246,20 @@ impl Builder<'_, '_> {
LibmIntrinsic::Custom(LibmCustomIntrinsic::Log1p) => {
assert_eq!(args.len(), 1);
let one = self.constant_float(args[0].ty, 1.0);
let add = self.add(args[0], one);
let add = self.fadd(args[0], one);
self.gl_op(GLOp::Log, result_type, [add])
}
LibmIntrinsic::Custom(LibmCustomIntrinsic::Exp10) => {
assert_eq!(args.len(), 1);
// exp10(x) == exp(x * log(10));
let log10 = self.constant_float(args[0].ty, 10.0f64.ln());
let mul = self.mul(args[0], log10);
let mul = self.fmul(args[0], log10);
self.gl_op(GLOp::Exp, result_type, [mul])
}
LibmIntrinsic::Custom(LibmCustomIntrinsic::Expm1) => {
let exp = self.gl_op(GLOp::Exp, args[0].ty, [args[0]]);
let one = self.constant_float(exp.ty, 1.0);
self.sub(exp, one)
self.fsub(exp, one)
}
LibmIntrinsic::Custom(LibmCustomIntrinsic::Erf) => {
self.undef_zombie(result_type, "Erf not supported yet")
Expand Down
18 changes: 4 additions & 14 deletions tests/compiletests/ui/dis/entry-pass-mode-cast-array.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,11 @@
OpLine %5 13 12
%6 = OpLoad %7 %8
OpLine %5 14 4
%9 = OpULessThan %10 %11 %12
OpNoLine
OpSelectionMerge %13 None
OpBranchConditional %9 %14 %15
%14 = OpLabel
OpBranch %13
%15 = OpLabel
OpReturn
%13 = OpLabel
OpLine %5 14 4
%16 = OpCompositeExtract %17 %6 0
%18 = OpFAdd %17 %16 %19
%20 = OpCompositeInsert %7 %18 %6 0
%9 = OpCompositeExtract %10 %6 0
%11 = OpFAdd %10 %9 %12
%13 = OpCompositeInsert %7 %11 %6 0
OpLine %5 15 4
OpStore %21 %20
OpStore %14 %13
OpNoLine
OpReturn
OpFunctionEnd
18 changes: 4 additions & 14 deletions tests/compiletests/ui/dis/issue-731.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,11 @@
OpLine %5 11 12
%6 = OpLoad %7 %8
OpLine %5 12 4
%9 = OpULessThan %10 %11 %12
OpNoLine
OpSelectionMerge %13 None
OpBranchConditional %9 %14 %15
%14 = OpLabel
OpBranch %13
%15 = OpLabel
OpReturn
%13 = OpLabel
OpLine %5 12 4
%16 = OpCompositeExtract %17 %6 0
%18 = OpFAdd %17 %16 %19
%20 = OpCompositeInsert %7 %18 %6 0
%9 = OpCompositeExtract %10 %6 0
%11 = OpFAdd %10 %9 %12
%13 = OpCompositeInsert %7 %11 %6 0
OpLine %5 13 4
OpStore %21 %20
OpStore %14 %13
OpNoLine
OpReturn
OpFunctionEnd
10 changes: 10 additions & 0 deletions tests/compiletests/ui/lang/u32/const_fold_div.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// build-pass

#![allow(unconditional_panic)]

use spirv_std::spirv;

#[spirv(fragment)]
pub fn const_fold_div(out: &mut u32) {
*out = 7u32 / 0;
}
76 changes: 76 additions & 0 deletions tests/difftests/tests/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions tests/difftests/tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ members = [
"lang/core/ops/matrix_ops/matrix_ops-rust",
"lang/core/ops/matrix_ops/matrix_ops-wgsl",
"lang/core/ops/bitwise_ops/bitwise_ops-rust",
"lang/core/ops/const_fold_int/const-expr-cpu",
"lang/core/ops/const_fold_int/const-expr-shader",
"lang/core/ops/const_fold_int/const-fold-cpu",
"lang/core/ops/const_fold_int/const-fold-shader",
"lang/core/ops/const_fold_int/dynamic-values-cpu",
"lang/core/ops/const_fold_int/dynamic-values-shader",
"lang/core/ops/bitwise_ops/bitwise_ops-wgsl",
"lang/core/ops/trig_ops/trig_ops-rust",
"lang/core/ops/trig_ops/trig_ops-wgsl",
Expand All @@ -53,6 +59,7 @@ difftest = { path = "../../../tests/difftests/lib" }
num-traits = { version = "0.2.15", default-features = false }
glam = { version = ">=0.22, <=0.29", default-features = false }
bytemuck = { version = "1.14", features = ["derive"] }
num_enum = { version = "0.7.4", default-features = false }

# Enable incremental by default in release mode.
[profile.release]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "const_fold_int-const-expr-cpu"
edition.workspace = true

[lints]
workspace = true

# GPU deps
[dependencies]
const_fold_int-const-fold-cpu = { path = "../const-fold-cpu" }

# CPU deps (for the test harness)
[target.'cfg(not(target_arch = "spirv"))'.dependencies]
difftest.workspace = true
bytemuck.workspace = true
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
use const_fold_int_const_fold_cpu::Variants;

fn main() {
const_fold_int_const_fold_cpu::cpu_driver::run(Variants::ConstExpr);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "const_fold_int-const-expr-shader"
edition.workspace = true

[lints]
workspace = true

[lib]
crate-type = ["dylib"]

# GPU deps
[dependencies]
const_fold_int-const-fold-cpu = { path = "../const-fold-cpu" }

# CPU deps (for the test harness)
[target.'cfg(not(target_arch = "spirv"))'.dependencies]
difftest.workspace = true
bytemuck.workspace = true
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#![cfg_attr(target_arch = "spirv", no_std)]
#![allow(arithmetic_overflow)]

pub use const_fold_int_const_fold_cpu::shader::main_cs;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
use const_fold_int_const_fold_cpu::Variants;

fn main() {
const_fold_int_const_fold_cpu::shader_driver::run(Variants::ConstExpr);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "const_fold_int-const-fold-cpu"
edition.workspace = true

[lints]
workspace = true

# GPU deps
[dependencies]
spirv-std.workspace = true
num_enum.workspace = true

# CPU deps (for the test harness)
[target.'cfg(not(target_arch = "spirv"))'.dependencies]
difftest.workspace = true
bytemuck.workspace = true
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use crate::{INTERESTING_PATTERNS, Variants};
use difftest::config::Config;

pub fn run(variant: Variants) {
let config = Config::from_path(std::env::args().nth(1).unwrap()).unwrap();
let result = variant
.eval(&INTERESTING_PATTERNS)
.into_iter()
.flatten()
.flatten()
.collect::<Vec<_>>();
config.write_result(&result).unwrap()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#![cfg_attr(target_arch = "spirv", no_std)]
#![allow(arithmetic_overflow)]

#[cfg(not(target_arch = "spirv"))]
pub mod cpu_driver;
pub mod shader;
#[cfg(not(target_arch = "spirv"))]
pub mod shader_driver;

use num_enum::{IntoPrimitive, TryFromPrimitive};

macro_rules! op_u {
($value:expr) => {
[
($value << 0) as u32,
($value << 1) as u32,
($value << 30) as u32,
($value << 31) as u32,
($value >> 0) as u32,
($value >> 1) as u32,
($value >> 30) as u32,
($value >> 31) as u32,
]
};
}

macro_rules! op_i {
($value:expr) => {
op_u!($value as i32)
};
}

macro_rules! interesting_patterns {
($op_name:ident) => {
[
$op_name!(0u32),
$op_name!(1u32),
$op_name!(0xFFFFFFFFu32),
$op_name!(0xDEADBEEFu32),
$op_name!(0b10011001100110011001100110011001u32),
$op_name!(0b10000000000000000000000000000001u32),
$op_name!(0x12345678u32),
$op_name!(0x87654321u32),
]
};
}

macro_rules! identity {
($expr:expr) => {
$expr
};
}

pub const INTERESTING_PATTERNS: [u32; 8] = interesting_patterns!(identity);

#[repr(u32)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, TryFromPrimitive, IntoPrimitive)]
pub enum Variants {
/// const folding in rust-gpu
ConstFold,
/// `const {}` expr for const eval within rustc
ConstExpr,
/// dynamic values from `input_patterns`
DynamicValues,
}

pub type EvalResult = [[[u32; 8]; 8]; 2];

impl Variants {
pub fn eval(&self, input_patterns: &[u32; 8]) -> EvalResult {
match self {
Variants::ConstFold => [interesting_patterns!(op_u), interesting_patterns!(op_i)],
Variants::ConstExpr => {
const { [interesting_patterns!(op_u), interesting_patterns!(op_i)] }
}
Variants::DynamicValues => [
[
op_u!(input_patterns[0]),
op_u!(input_patterns[1]),
op_u!(input_patterns[2]),
op_u!(input_patterns[3]),
op_u!(input_patterns[4]),
op_u!(input_patterns[5]),
op_u!(input_patterns[6]),
op_u!(input_patterns[7]),
],
[
op_i!(input_patterns[0]),
op_i!(input_patterns[1]),
op_i!(input_patterns[2]),
op_i!(input_patterns[3]),
op_i!(input_patterns[4]),
op_i!(input_patterns[5]),
op_i!(input_patterns[6]),
op_i!(input_patterns[7]),
],
],
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
use const_fold_int_const_fold_cpu::Variants;

fn main() {
const_fold_int_const_fold_cpu::cpu_driver::run(Variants::ConstFold);
}
Loading
Loading