Skip to content

Commit 42058cf

Browse files
committed
[naga] Add Literal::I64, for signed 64-bit integer literals.
Add an `I64` variant to `crate::Literal`, making `crate::Expression` suitable for representing `AbstractFloat` and `AbstractInt` values in the WGSL front end. Make validation reject uses of `Literal::I64` in constant and function expression arenas unconditionally. Add tests for this. Let the frontends and backends for languages that have 64-bit integers read/write them.
1 parent 16ec5b0 commit 42058cf

File tree

12 files changed

+200
-9
lines changed

12 files changed

+200
-9
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ Passing an owned value `window` to `Surface` will return a `Surface<'static>`. S
8080
- Introduce a new `Scalar` struct type for use in Naga's IR, and update all frontend, middle, and backend code appropriately. By @jimblandy in [#4673](https://github.com/gfx-rs/wgpu/pull/4673).
8181
- Add more metal keywords. By @fornwall in [#4707](https://github.com/gfx-rs/wgpu/pull/4707).
8282

83+
- Implement WGSL abstract types (by @jimblandy):
84+
- Add a new `naga::Literal` variant, `I64`, for signed 64-bit literals. [#4711](https://github.com/gfx-rs/wgpu/pull/4711)
85+
8386
### Bug Fixes
8487

8588
#### WGL

naga/src/back/glsl/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2410,6 +2410,9 @@ impl<'a, W: Write> Writer<'a, W> {
24102410
crate::Literal::U32(value) => write!(self.out, "{}u", value)?,
24112411
crate::Literal::I32(value) => write!(self.out, "{}", value)?,
24122412
crate::Literal::Bool(value) => write!(self.out, "{}", value)?,
2413+
crate::Literal::I64(_) => {
2414+
return Err(Error::Custom("GLSL has no 64-bit integer type".into()));
2415+
}
24132416
}
24142417
}
24152418
Expression::Constant(handle) => {

naga/src/back/hlsl/writer.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2041,6 +2041,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
20412041
crate::Literal::F32(value) => write!(self.out, "{value:?}")?,
20422042
crate::Literal::U32(value) => write!(self.out, "{}u", value)?,
20432043
crate::Literal::I32(value) => write!(self.out, "{}", value)?,
2044+
crate::Literal::I64(value) => write!(self.out, "{}L", value)?,
20442045
crate::Literal::Bool(value) => write!(self.out, "{}", value)?,
20452046
},
20462047
Expression::Constant(handle) => {

naga/src/back/msl/writer.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,6 +1274,9 @@ impl<W: Write> Writer<W> {
12741274
crate::Literal::I32(value) => {
12751275
write!(self.out, "{value}")?;
12761276
}
1277+
crate::Literal::I64(value) => {
1278+
write!(self.out, "{value}L")?;
1279+
}
12771280
crate::Literal::Bool(value) => {
12781281
write!(self.out, "{value}")?;
12791282
}

naga/src/back/spv/writer.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,6 +1179,9 @@ impl Writer {
11791179
crate::Literal::F32(value) => Instruction::constant_32bit(type_id, id, value.to_bits()),
11801180
crate::Literal::U32(value) => Instruction::constant_32bit(type_id, id, value),
11811181
crate::Literal::I32(value) => Instruction::constant_32bit(type_id, id, value as u32),
1182+
crate::Literal::I64(value) => {
1183+
Instruction::constant_64bit(type_id, id, value as u32, (value >> 32) as u32)
1184+
}
11821185
crate::Literal::Bool(true) => Instruction::constant_true(type_id, id),
11831186
crate::Literal::Bool(false) => Instruction::constant_false(type_id, id),
11841187
};

naga/src/back/wgsl/writer.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,13 +1091,16 @@ impl<W: Write> Writer<W> {
10911091
match literal {
10921092
// Floats are written using `Debug` instead of `Display` because it always appends the
10931093
// decimal part even it's zero
1094-
crate::Literal::F64(_) => {
1095-
return Err(Error::Custom("unsupported f64 literal".to_string()));
1096-
}
10971094
crate::Literal::F32(value) => write!(self.out, "{:?}", value)?,
10981095
crate::Literal::U32(value) => write!(self.out, "{}u", value)?,
10991096
crate::Literal::I32(value) => write!(self.out, "{}", value)?,
11001097
crate::Literal::Bool(value) => write!(self.out, "{}", value)?,
1098+
crate::Literal::F64(_) => {
1099+
return Err(Error::Custom("unsupported f64 literal".to_string()));
1100+
}
1101+
crate::Literal::I64(_) => {
1102+
return Err(Error::Custom("unsupported i64 literal".to_string()));
1103+
}
11011104
}
11021105
}
11031106
Expression::Constant(handle) => {

naga/src/front/spv/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4879,6 +4879,11 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
48794879
let low = self.next()?;
48804880
match width {
48814881
4 => crate::Literal::I32(low as i32),
4882+
8 => {
4883+
inst.expect(5)?;
4884+
let high = self.next()?;
4885+
crate::Literal::I64((u64::from(high) << 32 | u64::from(low)) as i64)
4886+
}
48824887
_ => return Err(Error::InvalidTypeWidth(width as u32)),
48834888
}
48844889
}

naga/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,7 @@ pub enum Literal {
869869
F32(f32),
870870
U32(u32),
871871
I32(i32),
872+
I64(i64),
872873
Bool(bool),
873874
}
874875

naga/src/proc/constant_evaluator.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -979,28 +979,36 @@ impl<'a> ConstantEvaluator<'a> {
979979
Literal::U32(v) => v as i32,
980980
Literal::F32(v) => v as i32,
981981
Literal::Bool(v) => v as i32,
982-
Literal::F64(_) => return Err(ConstantEvaluatorError::InvalidCastArg),
982+
Literal::F64(_) | Literal::I64(_) => {
983+
return Err(ConstantEvaluatorError::InvalidCastArg)
984+
}
983985
}),
984986
Sc::U32 => Literal::U32(match literal {
985987
Literal::I32(v) => v as u32,
986988
Literal::U32(v) => v,
987989
Literal::F32(v) => v as u32,
988990
Literal::Bool(v) => v as u32,
989-
Literal::F64(_) => return Err(ConstantEvaluatorError::InvalidCastArg),
991+
Literal::F64(_) | Literal::I64(_) => {
992+
return Err(ConstantEvaluatorError::InvalidCastArg)
993+
}
990994
}),
991995
Sc::F32 => Literal::F32(match literal {
992996
Literal::I32(v) => v as f32,
993997
Literal::U32(v) => v as f32,
994998
Literal::F32(v) => v,
995999
Literal::Bool(v) => v as u32 as f32,
996-
Literal::F64(_) => return Err(ConstantEvaluatorError::InvalidCastArg),
1000+
Literal::F64(_) | Literal::I64(_) => {
1001+
return Err(ConstantEvaluatorError::InvalidCastArg)
1002+
}
9971003
}),
9981004
Sc::BOOL => Literal::Bool(match literal {
9991005
Literal::I32(v) => v != 0,
10001006
Literal::U32(v) => v != 0,
10011007
Literal::F32(v) => v != 0.0,
10021008
Literal::Bool(v) => v,
1003-
Literal::F64(_) => return Err(ConstantEvaluatorError::InvalidCastArg),
1009+
Literal::F64(_) | Literal::I64(_) => {
1010+
return Err(ConstantEvaluatorError::InvalidCastArg)
1011+
}
10041012
}),
10051013
_ => return Err(ConstantEvaluatorError::InvalidCastArg),
10061014
};

naga/src/proc/mod.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ impl super::Scalar {
9494
kind: crate::ScalarKind::Float,
9595
width: 8,
9696
};
97+
pub const I64: Self = Self {
98+
kind: crate::ScalarKind::Sint,
99+
width: 8,
100+
};
97101
pub const BOOL: Self = Self {
98102
kind: crate::ScalarKind::Bool,
99103
width: crate::BOOL_WIDTH,
@@ -130,6 +134,7 @@ impl PartialEq for crate::Literal {
130134
(Self::F32(a), Self::F32(b)) => a.to_bits() == b.to_bits(),
131135
(Self::U32(a), Self::U32(b)) => a == b,
132136
(Self::I32(a), Self::I32(b)) => a == b,
137+
(Self::I64(a), Self::I64(b)) => a == b,
133138
(Self::Bool(a), Self::Bool(b)) => a == b,
134139
_ => false,
135140
}
@@ -159,6 +164,10 @@ impl std::hash::Hash for crate::Literal {
159164
hasher.write_u8(4);
160165
v.hash(hasher);
161166
}
167+
Self::I64(v) => {
168+
hasher.write_u8(5);
169+
v.hash(hasher);
170+
}
162171
}
163172
}
164173
}
@@ -170,6 +179,7 @@ impl crate::Literal {
170179
(value, crate::ScalarKind::Float, 4) => Some(Self::F32(value as _)),
171180
(value, crate::ScalarKind::Uint, 4) => Some(Self::U32(value as _)),
172181
(value, crate::ScalarKind::Sint, 4) => Some(Self::I32(value as _)),
182+
(value, crate::ScalarKind::Sint, 8) => Some(Self::I64(value as _)),
173183
(1, crate::ScalarKind::Bool, 4) => Some(Self::Bool(true)),
174184
(0, crate::ScalarKind::Bool, 4) => Some(Self::Bool(false)),
175185
_ => None,
@@ -186,7 +196,7 @@ impl crate::Literal {
186196

187197
pub const fn width(&self) -> crate::Bytes {
188198
match *self {
189-
Self::F64(_) => 8,
199+
Self::F64(_) | Self::I64(_) => 8,
190200
Self::F32(_) | Self::U32(_) | Self::I32(_) => 4,
191201
Self::Bool(_) => 1,
192202
}
@@ -197,6 +207,7 @@ impl crate::Literal {
197207
Self::F32(_) => crate::Scalar::F32,
198208
Self::U32(_) => crate::Scalar::U32,
199209
Self::I32(_) => crate::Scalar::I32,
210+
Self::I64(_) => crate::Scalar::I64,
200211
Self::Bool(_) => crate::Scalar::BOOL,
201212
}
202213
}

0 commit comments

Comments
 (0)