Skip to content

Commit f31876f

Browse files
LiedtkeV8-internal LUCI CQ
authored and
V8-internal LUCI CQ
committed
[wasm] Add more simd load instructions
Note that there are even more simd load instructions (those with "extract lane") but they have different signatures, so they will need separate Fuzzilli nodes and therefore are not included in this change. Bug: chromium:391916477 Change-Id: Iab3f1be0e0c640445ec181240508c2ee0228edab Reviewed-on: https://chrome-internal-review.googlesource.com/c/v8/fuzzilli/+/7988888 Reviewed-by: Carl Smith <[email protected]> Reviewed-by: Eva Herencsárová <[email protected]> Commit-Queue: Matthias Liedtke <[email protected]>
1 parent 583b81c commit f31876f

15 files changed

+269
-47
lines changed

Sources/Fuzzilli/Base/ProgramBuilder.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -3346,9 +3346,9 @@ public class ProgramBuilder {
33463346
}
33473347

33483348
@discardableResult
3349-
public func wasmI64x2LoadSplat(memory: Variable, dynamicOffset: Variable, staticOffset: Int64) -> Variable {
3349+
func wasmSimdLoad(kind: WasmSimdLoad.Kind, memory: Variable, dynamicOffset: Variable, staticOffset: Int64) -> Variable {
33503350
let isMemory64 = b.type(of: memory).wasmMemoryType!.isMemory64
3351-
return b.emit(WasmI64x2LoadSplat(staticOffset: staticOffset, isMemory64: isMemory64), withInputs: [memory, dynamicOffset]).output
3351+
return b.emit(WasmSimdLoad(kind: kind, staticOffset: staticOffset, isMemory64: isMemory64), withInputs: [memory, dynamicOffset]).output
33523352
}
33533353
}
33543354

Sources/Fuzzilli/CodeGen/CodeGeneratorWeights.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ public let codeGeneratorWeights = [
292292
"WasmSimd128CompareGenerator": 5,
293293
"WasmI64x2SplatGenerator": 5,
294294
"WasmI64x2ExtractLaneGenerator": 5,
295-
"WasmI64x2LoadSplatGenerator": 5,
295+
"WasmSimdLoadGenerator": 5,
296296

297297
"WasmSelectGenerator": 10,
298298
]

Sources/Fuzzilli/CodeGen/WasmCodeGenerators.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -850,13 +850,13 @@ public let WasmCodeGenerators: [CodeGenerator] = [
850850
function.wasmI64x2ExtractLane(input, 0)
851851
},
852852

853-
CodeGenerator("WasmI64x2LoadSplatGenerator", inContext: .wasmFunction, inputs: .required(.object(ofGroup: "WasmMemory"))) { b, memory in
853+
CodeGenerator("WasmSimdLoadGenerator", inContext: .wasmFunction, inputs: .required(.object(ofGroup: "WasmMemory"))) { b, memory in
854854
if (b.hasZeroPages(memory: memory)) { return }
855855

856856
let function = b.currentWasmModule.currentWasmFunction
857857
let (dynamicOffset, staticOffset) = b.generateMemoryIndexes(forMemory: memory)
858-
859-
function.wasmI64x2LoadSplat(memory: memory, dynamicOffset: dynamicOffset, staticOffset: staticOffset)
858+
let kind = chooseUniform(from: WasmSimdLoad.Kind.allCases)
859+
function.wasmSimdLoad(kind: kind, memory: memory, dynamicOffset: dynamicOffset, staticOffset: staticOffset)
860860
},
861861

862862
// TODO: Add three generators for JSPI

Sources/Fuzzilli/FuzzIL/Instruction.swift

+61-4
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,33 @@ extension Instruction: ProtobufConvertible {
431431
}
432432
}
433433

434+
func convertWasmSimdLoadKind(_ loadKind: WasmSimdLoad.Kind) -> Fuzzilli_Protobuf_WasmSimdLoadKind {
435+
switch loadKind {
436+
case .LoadS128:
437+
return .loads128
438+
case .Load8x8S:
439+
return .load8X8S
440+
case .Load8x8U:
441+
return .load8X8U
442+
case .Load16x4S:
443+
return .load16X4S
444+
case .Load16x4U:
445+
return .load16X4U
446+
case .Load32x2S:
447+
return .load32X2S
448+
case .Load32x2U:
449+
return .load32X2U
450+
case .Load8Splat:
451+
return .load8Splat
452+
case .Load16Splat:
453+
return .load16Splat
454+
case .Load32Splat:
455+
return .load32Splat
456+
case .Load64Splat:
457+
return .load64Splat
458+
}
459+
}
460+
434461
func convertWasmGlobal(wasmGlobal: WasmGlobal) -> Fuzzilli_Protobuf_WasmGlobal.OneOf_WasmGlobal {
435462
switch wasmGlobal {
436463
case .wasmi32(let val):
@@ -1303,8 +1330,9 @@ extension Instruction: ProtobufConvertible {
13031330
$0.wasmI64X2Splat = Fuzzilli_Protobuf_WasmI64x2Splat()
13041331
case .wasmI64x2ExtractLane(_):
13051332
$0.wasmI64X2ExtractLane = Fuzzilli_Protobuf_WasmI64x2ExtractLane()
1306-
case .wasmI64x2LoadSplat(let op):
1307-
$0.wasmI64X2LoadSplat = Fuzzilli_Protobuf_WasmI64x2LoadSplat.with {
1333+
case .wasmSimdLoad(let op):
1334+
$0.wasmSimdLoad = Fuzzilli_Protobuf_WasmSimdLoad.with {
1335+
$0.kind = convertWasmSimdLoadKind(op.kind)
13081336
$0.staticOffset = op.staticOffset
13091337
$0.isMemory64 = op.isMemory64
13101338
}
@@ -1421,6 +1449,35 @@ extension Instruction: ProtobufConvertible {
14211449
}
14221450
}
14231451

1452+
func convertProtoWasmSimdLoadKind(_ loadKind: Fuzzilli_Protobuf_WasmSimdLoadKind) -> WasmSimdLoad.Kind {
1453+
switch loadKind {
1454+
case .loads128:
1455+
return .LoadS128
1456+
case .load8X8S:
1457+
return .Load8x8S
1458+
case .load8X8U:
1459+
return .Load8x8U
1460+
case .load16X4S:
1461+
return .Load16x4S
1462+
case .load16X4U:
1463+
return .Load16x4U
1464+
case .load32X2S:
1465+
return .Load32x2S
1466+
case .load32X2U:
1467+
return .Load32x2U
1468+
case .load8Splat:
1469+
return .Load8Splat
1470+
case .load16Splat:
1471+
return .Load16Splat
1472+
case .load32Splat:
1473+
return .Load32Splat
1474+
case .load64Splat:
1475+
return .Load64Splat
1476+
case .UNRECOGNIZED(let i):
1477+
fatalError("Invalid WasmSimdLoadKind \(i)")
1478+
}
1479+
}
1480+
14241481
func convertWasmGlobal(_ proto: Fuzzilli_Protobuf_WasmGlobal) -> WasmGlobal {
14251482
switch proto.wasmGlobal {
14261483
case .nullref(_):
@@ -2093,8 +2150,8 @@ extension Instruction: ProtobufConvertible {
20932150
op = WasmI64x2Splat()
20942151
case .wasmI64X2ExtractLane(_):
20952152
op = WasmI64x2ExtractLane(lane: 0)
2096-
case .wasmI64X2LoadSplat(let p):
2097-
op = WasmI64x2LoadSplat(staticOffset: p.staticOffset, isMemory64: p.isMemory64)
2153+
case .wasmSimdLoad(let p):
2154+
op = WasmSimdLoad(kind: convertProtoWasmSimdLoadKind(p.kind), staticOffset: p.staticOffset, isMemory64: p.isMemory64)
20982155
}
20992156

21002157
guard op.numInputs + op.numOutputs + op.numInnerOutputs == inouts.count else {

Sources/Fuzzilli/FuzzIL/Opcodes.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ enum Opcode {
308308
case wasmSimd128FloatBinOp(WasmSimd128FloatBinOp)
309309
case wasmI64x2Splat(WasmI64x2Splat)
310310
case wasmI64x2ExtractLane(WasmI64x2ExtractLane)
311-
case wasmI64x2LoadSplat(WasmI64x2LoadSplat)
311+
case wasmSimdLoad(WasmSimdLoad)
312312

313313
case wasmUnreachable(WasmUnreachable)
314314
case wasmSelect(WasmSelect)

Sources/Fuzzilli/FuzzIL/WasmOperations.swift

+21-4
Original file line numberDiff line numberDiff line change
@@ -1523,13 +1523,30 @@ final class WasmI64x2ExtractLane: WasmOperation {
15231523
}
15241524
}
15251525

1526-
final class WasmI64x2LoadSplat: WasmOperation {
1527-
override var opcode: Opcode { .wasmI64x2LoadSplat(self) }
1528-
1526+
final class WasmSimdLoad: WasmOperation {
1527+
enum Kind: UInt8, CaseIterable {
1528+
// TODO(mliedtke): Test all the other variants!
1529+
case LoadS128 = 0x00
1530+
case Load8x8S = 0x01
1531+
case Load8x8U = 0x02
1532+
case Load16x4S = 0x03
1533+
case Load16x4U = 0x04
1534+
case Load32x2S = 0x05
1535+
case Load32x2U = 0x06
1536+
case Load8Splat = 0x07
1537+
case Load16Splat = 0x08
1538+
case Load32Splat = 0x09
1539+
case Load64Splat = 0x0A
1540+
}
1541+
1542+
override var opcode: Opcode { .wasmSimdLoad(self) }
1543+
1544+
let kind: Kind
15291545
let staticOffset: Int64
15301546
let isMemory64: Bool
15311547

1532-
init(staticOffset: Int64, isMemory64: Bool) {
1548+
init(kind: Kind, staticOffset: Int64, isMemory64: Bool) {
1549+
self.kind = kind
15331550
self.staticOffset = staticOffset
15341551
self.isMemory64 = isMemory64
15351552
let dynamicOffsetType = isMemory64 ? ILType.wasmi64 : ILType.wasmi32

Sources/Fuzzilli/Lifting/FuzzILLifter.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -1099,8 +1099,8 @@ public class FuzzILLifter: Lifter {
10991099
case .wasmI64x2ExtractLane(let op):
11001100
w.emit("\(output()) <- WasmI64x2ExtractLane \(input(0)) \(op.lane)")
11011101

1102-
case .wasmI64x2LoadSplat(_):
1103-
w.emit("\(output()) <- WasmI64x2LoadSplat \(input(0))")
1102+
case .wasmSimdLoad(let op):
1103+
w.emit("\(output()) <- WasmSimdLoad \(op.kind) \(input(0)) + \(op.staticOffset)")
11041104

11051105
default:
11061106
fatalError("No FuzzIL lifting for this operation!")

Sources/Fuzzilli/Lifting/JavaScriptLifter.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -1607,7 +1607,7 @@ public class JavaScriptLifter: Lifter {
16071607
.wasmSimd128Compare(_),
16081608
.wasmI64x2Splat(_),
16091609
.wasmI64x2ExtractLane(_),
1610-
.wasmI64x2LoadSplat(_):
1610+
.wasmSimdLoad(_):
16111611
fatalError("unreachable")
16121612
}
16131613

Sources/Fuzzilli/Lifting/WasmLifter.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -1071,7 +1071,7 @@ public class WasmLifter {
10711071
try memoryOpImportAnalysis(instr: instr, isMemory64: op.isMemory64)
10721072
case .wasmMemoryStore(let op):
10731073
try memoryOpImportAnalysis(instr: instr, isMemory64: op.isMemory64)
1074-
case .wasmI64x2LoadSplat(let op):
1074+
case .wasmSimdLoad(let op):
10751075
try memoryOpImportAnalysis(instr: instr, isMemory64: op.isMemory64)
10761076
case .wasmTableGet(_),
10771077
.wasmTableSet(_):
@@ -1556,9 +1556,9 @@ public class WasmLifter {
15561556
return Data([0xFD]) + Leb128.unsignedEncode(0x12)
15571557
case .wasmI64x2ExtractLane(let op):
15581558
return Data([0xFD]) + Leb128.unsignedEncode(0x1D) + Leb128.unsignedEncode(op.lane)
1559-
case .wasmI64x2LoadSplat(let op):
1559+
case .wasmSimdLoad(let op):
15601560
// The memory immediate is {staticOffset, align} where align is 0 by default. Use signed encoding for potential bad (i.e. negative) offsets.
1561-
return Data([0xFD]) + Leb128.unsignedEncode(0x0A) + Leb128.unsignedEncode(0) + Leb128.signedEncode(Int(op.staticOffset))
1561+
return Data([0xFD, op.kind.rawValue]) + Leb128.unsignedEncode(0) + Leb128.signedEncode(Int(op.staticOffset))
15621562

15631563
default:
15641564
fatalError("unreachable")

Sources/Fuzzilli/Mutators/OperationMutator.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ public class OperationMutator: BaseInstructionMutator {
377377
case .wasmI64x2ExtractLane(let op):
378378
// TODO: ?
379379
newOp = op
380-
case .wasmI64x2LoadSplat(let op):
380+
case .wasmSimdLoad(let op):
381381
// TODO: ?
382382
newOp = op
383383
case .createWasmJSTag(let op):

Sources/Fuzzilli/Protobuf/operations.pb.swift

+104-10
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,76 @@ public enum Fuzzilli_Protobuf_WasmMemoryStoreType: SwiftProtobuf.Enum, Swift.Cas
751751

752752
}
753753

754+
public enum Fuzzilli_Protobuf_WasmSimdLoadKind: SwiftProtobuf.Enum, Swift.CaseIterable {
755+
public typealias RawValue = Int
756+
case loads128 // = 0
757+
case load8X8S // = 1
758+
case load8X8U // = 2
759+
case load16X4S // = 3
760+
case load16X4U // = 4
761+
case load32X2S // = 5
762+
case load32X2U // = 6
763+
case load8Splat // = 7
764+
case load16Splat // = 8
765+
case load32Splat // = 9
766+
case load64Splat // = 10
767+
case UNRECOGNIZED(Int)
768+
769+
public init() {
770+
self = .loads128
771+
}
772+
773+
public init?(rawValue: Int) {
774+
switch rawValue {
775+
case 0: self = .loads128
776+
case 1: self = .load8X8S
777+
case 2: self = .load8X8U
778+
case 3: self = .load16X4S
779+
case 4: self = .load16X4U
780+
case 5: self = .load32X2S
781+
case 6: self = .load32X2U
782+
case 7: self = .load8Splat
783+
case 8: self = .load16Splat
784+
case 9: self = .load32Splat
785+
case 10: self = .load64Splat
786+
default: self = .UNRECOGNIZED(rawValue)
787+
}
788+
}
789+
790+
public var rawValue: Int {
791+
switch self {
792+
case .loads128: return 0
793+
case .load8X8S: return 1
794+
case .load8X8U: return 2
795+
case .load16X4S: return 3
796+
case .load16X4U: return 4
797+
case .load32X2S: return 5
798+
case .load32X2U: return 6
799+
case .load8Splat: return 7
800+
case .load16Splat: return 8
801+
case .load32Splat: return 9
802+
case .load64Splat: return 10
803+
case .UNRECOGNIZED(let i): return i
804+
}
805+
}
806+
807+
// The compiler won't synthesize support with the UNRECOGNIZED case.
808+
public static let allCases: [Fuzzilli_Protobuf_WasmSimdLoadKind] = [
809+
.loads128,
810+
.load8X8S,
811+
.load8X8U,
812+
.load16X4S,
813+
.load16X4U,
814+
.load32X2S,
815+
.load32X2U,
816+
.load8Splat,
817+
.load16Splat,
818+
.load32Splat,
819+
.load64Splat,
820+
]
821+
822+
}
823+
754824
/// Parameters used by function definitions, not an operation by itself.
755825
public struct Fuzzilli_Protobuf_Parameters: Sendable {
756826
// SwiftProtobuf.Message conformance is added in an extension below. See the
@@ -4309,11 +4379,13 @@ public struct Fuzzilli_Protobuf_WasmI64x2ExtractLane: Sendable {
43094379
public init() {}
43104380
}
43114381

4312-
public struct Fuzzilli_Protobuf_WasmI64x2LoadSplat: Sendable {
4382+
public struct Fuzzilli_Protobuf_WasmSimdLoad: Sendable {
43134383
// SwiftProtobuf.Message conformance is added in an extension below. See the
43144384
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
43154385
// methods supported on all messages.
43164386

4387+
public var kind: Fuzzilli_Protobuf_WasmSimdLoadKind = .loads128
4388+
43174389
public var staticOffset: Int64 = 0
43184390

43194391
public var isMemory64: Bool = false
@@ -4488,6 +4560,22 @@ extension Fuzzilli_Protobuf_WasmMemoryStoreType: SwiftProtobuf._ProtoNameProvidi
44884560
]
44894561
}
44904562

4563+
extension Fuzzilli_Protobuf_WasmSimdLoadKind: SwiftProtobuf._ProtoNameProviding {
4564+
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
4565+
0: .same(proto: "LOADS128"),
4566+
1: .same(proto: "LOAD8x8S"),
4567+
2: .same(proto: "LOAD8x8U"),
4568+
3: .same(proto: "LOAD16x4S"),
4569+
4: .same(proto: "LOAD16x4U"),
4570+
5: .same(proto: "LOAD32x2S"),
4571+
6: .same(proto: "LOAD32x2U"),
4572+
7: .same(proto: "LOAD8SPLAT"),
4573+
8: .same(proto: "LOAD16SPLAT"),
4574+
9: .same(proto: "LOAD32SPLAT"),
4575+
10: .same(proto: "LOAD64SPLAT"),
4576+
]
4577+
}
4578+
44914579
extension Fuzzilli_Protobuf_Parameters: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
44924580
public static let protoMessageName: String = _protobuf_package + ".Parameters"
44934581
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
@@ -12597,11 +12685,12 @@ extension Fuzzilli_Protobuf_WasmI64x2ExtractLane: SwiftProtobuf.Message, SwiftPr
1259712685
}
1259812686
}
1259912687

12600-
extension Fuzzilli_Protobuf_WasmI64x2LoadSplat: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
12601-
public static let protoMessageName: String = _protobuf_package + ".WasmI64x2LoadSplat"
12688+
extension Fuzzilli_Protobuf_WasmSimdLoad: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
12689+
public static let protoMessageName: String = _protobuf_package + ".WasmSimdLoad"
1260212690
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
12603-
1: .same(proto: "staticOffset"),
12604-
2: .same(proto: "isMemory64"),
12691+
1: .same(proto: "kind"),
12692+
2: .same(proto: "staticOffset"),
12693+
3: .same(proto: "isMemory64"),
1260512694
]
1260612695

1260712696
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@@ -12610,24 +12699,29 @@ extension Fuzzilli_Protobuf_WasmI64x2LoadSplat: SwiftProtobuf.Message, SwiftProt
1261012699
// allocates stack space for every case branch when no optimizations are
1261112700
// enabled. https://github.com/apple/swift-protobuf/issues/1034
1261212701
switch fieldNumber {
12613-
case 1: try { try decoder.decodeSingularInt64Field(value: &self.staticOffset) }()
12614-
case 2: try { try decoder.decodeSingularBoolField(value: &self.isMemory64) }()
12702+
case 1: try { try decoder.decodeSingularEnumField(value: &self.kind) }()
12703+
case 2: try { try decoder.decodeSingularInt64Field(value: &self.staticOffset) }()
12704+
case 3: try { try decoder.decodeSingularBoolField(value: &self.isMemory64) }()
1261512705
default: break
1261612706
}
1261712707
}
1261812708
}
1261912709

1262012710
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
12711+
if self.kind != .loads128 {
12712+
try visitor.visitSingularEnumField(value: self.kind, fieldNumber: 1)
12713+
}
1262112714
if self.staticOffset != 0 {
12622-
try visitor.visitSingularInt64Field(value: self.staticOffset, fieldNumber: 1)
12715+
try visitor.visitSingularInt64Field(value: self.staticOffset, fieldNumber: 2)
1262312716
}
1262412717
if self.isMemory64 != false {
12625-
try visitor.visitSingularBoolField(value: self.isMemory64, fieldNumber: 2)
12718+
try visitor.visitSingularBoolField(value: self.isMemory64, fieldNumber: 3)
1262612719
}
1262712720
try unknownFields.traverse(visitor: &visitor)
1262812721
}
1262912722

12630-
public static func ==(lhs: Fuzzilli_Protobuf_WasmI64x2LoadSplat, rhs: Fuzzilli_Protobuf_WasmI64x2LoadSplat) -> Bool {
12723+
public static func ==(lhs: Fuzzilli_Protobuf_WasmSimdLoad, rhs: Fuzzilli_Protobuf_WasmSimdLoad) -> Bool {
12724+
if lhs.kind != rhs.kind {return false}
1263112725
if lhs.staticOffset != rhs.staticOffset {return false}
1263212726
if lhs.isMemory64 != rhs.isMemory64 {return false}
1263312727
if lhs.unknownFields != rhs.unknownFields {return false}

0 commit comments

Comments
 (0)