Skip to content

Commit ae221d0

Browse files
committed
Add Vector constant values and constant shuffling
1 parent aba6dab commit ae221d0

File tree

3 files changed

+96
-0
lines changed

3 files changed

+96
-0
lines changed

Sources/LLVM/VectorType.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,23 @@ public struct VectorType: IRType {
2222
self.count = count
2323
}
2424

25+
/// Creates a constant value of this vector type initialized with the given
26+
/// list of values.
27+
///
28+
/// - precondition: values.count == vector.count
29+
/// - parameter values: A list of values of elements of this vector.
30+
///
31+
/// - returns: A value representing a constant value of this vector type.
32+
public func constant(_ values: [IRValue]) -> Constant<Vector> {
33+
assert(numericCast(values.count) == LLVMGetVectorSize(asLLVM()),
34+
"The number of values must match the number of elements in the vector")
35+
var vals = values.map { $0.asLLVM() as Optional }
36+
return vals.withUnsafeMutableBufferPointer { buf in
37+
return Constant(llvm: LLVMConstVector(buf.baseAddress,
38+
UInt32(buf.count)))
39+
}
40+
}
41+
2542
/// Retrieves the underlying LLVM type object.
2643
public func asLLVM() -> LLVMTypeRef {
2744
return LLVMVectorType(elementType.asLLVM(), UInt32(count))

Tests/LLVMTests/ConstantSpec.swift

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,62 @@ class ConstantSpec : XCTestCase {
138138
// STRUCTCONSTGETELEMENT-NEXT: }
139139
module.dump()
140140
})
141+
142+
XCTAssert(fileCheckOutput(of: .stderr, withPrefixes: ["VECTORCONSTSHUFFLE-IDENTITY"]) {
143+
// VECTORCONSTSHUFFLE-IDENTITY: ; ModuleID = '[[ModuleName:ConstantTest]]'
144+
// VECTORCONSTSHUFFLE-IDENTITY-NEXT: source_filename = "[[ModuleName]]"
145+
let module = Module(name: "ConstantTest")
146+
let builder = IRBuilder(module: module)
147+
148+
let vecTy = VectorType(elementType: IntType.int32, count: 4)
149+
// VECTORCONSTSHUFFLE-IDENTITY: define <4 x i32> @main() {
150+
let main = builder.addFunction("main",
151+
type: FunctionType(argTypes: [],
152+
returnType: vecTy))
153+
154+
let vec1 = vecTy.constant([ 1, 2, 3, 4 ] as [Int32])
155+
let mask = vecTy.constant([ 0, 1, 2, 3 ] as [Int32])
156+
157+
// VECTORCONSTSHUFFLE-IDENTITY-NEXT: entry:
158+
let entry = main.appendBasicBlock(named: "entry")
159+
builder.positionAtEnd(of: entry)
160+
161+
let firstElement = Constant<Vector>.buildShuffleVector(vec1, and: .undef(vecTy), mask: mask)
162+
163+
// VECTORCONSTSHUFFLE-IDENTITY-NEXT: ret <4 x i32> <i32 1, i32 2, i32 3, i32 4>
164+
builder.buildRet(firstElement)
165+
// VECTORCONSTSHUFFLE-IDENTITY-NEXT: }
166+
module.dump()
167+
})
168+
169+
XCTAssert(fileCheckOutput(of: .stderr, withPrefixes: ["VECTORCONSTSHUFFLE"]) {
170+
// VECTORCONSTSHUFFLE: ; ModuleID = '[[ModuleName:ConstantTest]]'
171+
// VECTORCONSTSHUFFLE-NEXT: source_filename = "[[ModuleName]]"
172+
let module = Module(name: "ConstantTest")
173+
let builder = IRBuilder(module: module)
174+
175+
let maskTy = VectorType(elementType: IntType.int32, count: 8)
176+
// VECTORCONSTSHUFFLE: define <8 x i32> @main() {
177+
let main = builder.addFunction("main",
178+
type: FunctionType(argTypes: [],
179+
returnType: maskTy))
180+
181+
let vecTy = VectorType(elementType: IntType.int32, count: 4)
182+
let vec1 = vecTy.constant([ 1, 2, 3, 4 ] as [Int32])
183+
let vec2 = vecTy.constant([ 5, 6, 7, 8 ] as [Int32])
184+
let mask = maskTy.constant([ 1, 3, 5, 7, 0, 2, 4, 6 ] as [Int32])
185+
186+
// VECTORCONSTSHUFFLE-NEXT: entry:
187+
let entry = main.appendBasicBlock(named: "entry")
188+
builder.positionAtEnd(of: entry)
189+
190+
let firstElement = Constant<Vector>.buildShuffleVector(vec1, and: vec2, mask: mask)
191+
192+
// VECTORCONSTSHUFFLE-NEXT: ret <8 x i32> <i32 2, i32 4, i32 6, i32 8, i32 1, i32 3, i32 5, i32 7>
193+
builder.buildRet(firstElement)
194+
// VECTORCONSTSHUFFLE-NEXT: }
195+
module.dump()
196+
})
141197
}
142198

143199
#if !os(macOS)

Tests/LLVMTests/IRBuilderSpec.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ class IRBuilderSpec : XCTestCase {
3838
var g2 = builder.addGlobal("b", type: IntType.int32)
3939
g2.initializer = Int32(1)
4040

41+
// IRBUILDERARITH-NEXT: @vec1 = global <8 x i64> <i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1>
42+
// IRBUILDERARITH-NEXT: @vec2 = global <8 x i64> <i64 2, i64 2, i64 2, i64 2, i64 2, i64 2, i64 2, i64 2>
43+
let vecTy = VectorType(elementType: IntType.int32, count: 8)
44+
let gVec1 = builder.addGlobal("vec1", initializer: vecTy.constant([ 1, 1, 1, 1, 1, 1, 1, 1 ]))
45+
let gVec2 = builder.addGlobal("vec2", initializer: vecTy.constant([ 2, 2, 2, 2, 2, 2, 2, 2 ]))
46+
4147
// IRBUILDERARITH: define void @main() {
4248
let main = builder.addFunction("main",
4349
type: FunctionType(argTypes: [],
@@ -51,6 +57,12 @@ class IRBuilderSpec : XCTestCase {
5157
// IRBUILDERARITH-NEXT: [[B_LOAD:%[0-9]+]] = load i32, i32* @b
5258
let vg2 = builder.buildLoad(g2)
5359

60+
// IRBUILDERARITH-NEXT: [[VEC1_LOAD:%[0-9]+]] = load <8 x i64>, <8 x i64>* @vec1
61+
let vgVec1 = builder.buildLoad(gVec1)
62+
63+
// IRBUILDERARITH-NEXT: [[VEC2_LOAD:%[0-9]+]] = load <8 x i64>, <8 x i64>* @vec2
64+
let vgVec2 = builder.buildLoad(gVec2)
65+
5466
// IRBUILDERARITH-NEXT: {{%[0-9]+}} = add i32 [[A_LOAD]], [[B_LOAD]]
5567
_ = builder.buildAdd(vg1, vg2)
5668
// IRBUILDERARITH-NEXT: {{%[0-9]+}} = sub i32 [[A_LOAD]], [[B_LOAD]]
@@ -76,6 +88,17 @@ class IRBuilderSpec : XCTestCase {
7688
// IRBUILDERARITH-NEXT: {{%[0-9]+}} = mul nuw i32 [[A_LOAD]], [[B_LOAD]]
7789
_ = builder.buildMul(vg1, vg2, overflowBehavior: .noUnsignedWrap)
7890

91+
// IRBUILDERARITH-NEXT: {{%[0-9]+}} = add <8 x i64> [[VEC1_LOAD]], [[VEC2_LOAD]]
92+
_ = builder.buildAdd(vgVec1, vgVec2)
93+
// IRBUILDERARITH-NEXT: {{%[0-9]+}} = sub <8 x i64> [[VEC1_LOAD]], [[VEC2_LOAD]]
94+
_ = builder.buildSub(vgVec1, vgVec2)
95+
// IRBUILDERARITH-NEXT: {{%[0-9]+}} = mul <8 x i64> [[VEC1_LOAD]], [[VEC2_LOAD]]
96+
_ = builder.buildMul(vgVec1, vgVec2)
97+
// IRBUILDERARITH-NEXT: {{%[0-9]+}} = sdiv <8 x i64> [[VEC1_LOAD]], [[VEC2_LOAD]]
98+
_ = builder.buildDiv(vgVec1, vgVec2, signed: true)
99+
// IRBUILDERARITH-NEXT: {{%[0-9]+}} = udiv <8 x i64> [[VEC1_LOAD]], [[VEC2_LOAD]]
100+
_ = builder.buildDiv(vgVec1, vgVec2, signed: false)
101+
79102
// IRBUILDERARITH-NEXT: {{%[0-9]+}} = sub i32 0, [[A_LOAD]]
80103
_ = builder.buildNeg(vg1, overflowBehavior: .default)
81104
// IRBUILDERARITH-NEXT: {{%[0-9]+}} = sub nuw i32 0, [[A_LOAD]]

0 commit comments

Comments
 (0)