Skip to content

Commit d88af63

Browse files
authored
Support lowering of constant expression vectors inside metadata (#1175)
1 parent 44f6f57 commit d88af63

File tree

2 files changed

+91
-12
lines changed

2 files changed

+91
-12
lines changed

lib/SPIRV/SPIRVLowerConstExpr.cpp

+27-12
Original file line numberDiff line numberDiff line change
@@ -167,22 +167,23 @@ void SPIRVLowerConstExprBase::visit(Module *M) {
167167
};
168168

169169
WorkList.pop_front();
170-
for (unsigned OI = 0, OE = II->getNumOperands(); OI != OE; ++OI) {
171-
auto Op = II->getOperand(OI);
172-
auto *Vec = dyn_cast<ConstantVector>(Op);
173-
if (Vec && std::all_of(Vec->op_begin(), Vec->op_end(), [](Value *V) {
170+
auto LowerConstantVec = [&II, &LowerOp, &WorkList,
171+
&M](ConstantVector *Vec,
172+
unsigned NumOfOp) -> Value * {
173+
if (std::all_of(Vec->op_begin(), Vec->op_end(), [](Value *V) {
174174
return isa<ConstantExpr>(V) || isa<Function>(V);
175175
})) {
176-
// Expand a vector of constexprs and construct it back with series of
177-
// insertelement instructions
176+
// Expand a vector of constexprs and construct it back with
177+
// series of insertelement instructions
178178
std::list<Value *> OpList;
179179
std::transform(Vec->op_begin(), Vec->op_end(),
180180
std::back_inserter(OpList),
181181
[LowerOp](Value *V) { return LowerOp(V); });
182182
Value *Repl = nullptr;
183183
unsigned Idx = 0;
184184
auto *PhiII = dyn_cast<PHINode>(II);
185-
auto *InsPoint = PhiII ? &PhiII->getIncomingBlock(OI)->back() : II;
185+
auto *InsPoint =
186+
PhiII ? &PhiII->getIncomingBlock(NumOfOp)->back() : II;
186187
std::list<Instruction *> ReplList;
187188
for (auto V : OpList) {
188189
if (auto *Inst = dyn_cast<Instruction>(V))
@@ -192,20 +193,34 @@ void SPIRVLowerConstExprBase::visit(Module *M) {
192193
ConstantInt::get(Type::getInt32Ty(M->getContext()), Idx++), "",
193194
InsPoint);
194195
}
195-
II->replaceUsesOfWith(Op, Repl);
196196
WorkList.splice(WorkList.begin(), ReplList);
197+
return Repl;
198+
}
199+
return nullptr;
200+
};
201+
202+
for (unsigned OI = 0, OE = II->getNumOperands(); OI != OE; ++OI) {
203+
auto *Op = II->getOperand(OI);
204+
if (auto *Vec = dyn_cast<ConstantVector>(Op)) {
205+
Value *ReplInst = LowerConstantVec(Vec, OI);
206+
if (ReplInst)
207+
II->replaceUsesOfWith(Op, ReplInst);
197208
} else if (auto CE = dyn_cast<ConstantExpr>(Op)) {
198209
WorkList.push_front(cast<Instruction>(LowerOp(CE)));
199210
} else if (auto MDAsVal = dyn_cast<MetadataAsValue>(Op)) {
200211
Metadata *MD = MDAsVal->getMetadata();
201212
if (auto ConstMD = dyn_cast<ConstantAsMetadata>(MD)) {
202213
Constant *C = ConstMD->getValue();
203-
if (auto CE = dyn_cast<ConstantExpr>(C)) {
204-
Value *RepInst = LowerOp(CE);
205-
Metadata *RepMD = ValueAsMetadata::get(RepInst);
214+
Value *ReplInst = nullptr;
215+
if (auto *Vec = dyn_cast<ConstantVector>(C))
216+
ReplInst = LowerConstantVec(Vec, OI);
217+
if (auto *CE = dyn_cast<ConstantExpr>(C))
218+
ReplInst = LowerOp(CE);
219+
if (ReplInst) {
220+
Metadata *RepMD = ValueAsMetadata::get(ReplInst);
206221
Value *RepMDVal = MetadataAsValue::get(M->getContext(), RepMD);
207222
II->setOperand(OI, RepMDVal);
208-
WorkList.push_front(cast<Instruction>(RepInst));
223+
WorkList.push_front(cast<Instruction>(ReplInst));
209224
}
210225
}
211226
}

test/vector-metadata-constexpr.ll

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
; RUN: llvm-as %s -o %t.bc
2+
; RUN: llvm-spirv -s %t.bc -o - | llvm-dis -o - | FileCheck %s
3+
; RUN: llvm-spirv %t.bc
4+
5+
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
6+
target triple = "spir64-unknown-unknown"
7+
8+
; Function Attrs: nounwind ssp uwtable
9+
define void @foo() #0 !dbg !4 {
10+
entry:
11+
call void @llvm.dbg.value(metadata <3 x i8> <i8 add (i8 extractelement (<8 x i8> bitcast (<2 x i32> <i32 65793, i32 65793> to <8 x i8>), i32 0), i8 extractelement (<8 x i8> bitcast (<2 x i32> <i32 131586, i32 131586> to <8 x i8>), i32 0)), i8 add (i8 extractelement (<8 x i8> bitcast (<2 x i32> <i32 65793, i32 65793> to <8 x i8>), i32 1), i8 extractelement (<8 x i8> bitcast (<2 x i32> <i32 131586, i32 131586> to <8 x i8>), i32 1)), i8 add (i8 extractelement (<8 x i8> bitcast (<2 x i32> <i32 65793, i32 65793> to <8 x i8>), i32 2), i8 extractelement (<8 x i8> bitcast (<2 x i32> <i32 131586, i32 131586> to <8 x i8>), i32 2))>, metadata !12, metadata !DIExpression()), !dbg !18
12+
ret void, !dbg !20
13+
; CHECK: %0 = bitcast <2 x i32> <i32 65793, i32 65793> to <8 x i8>
14+
; CHECK: %1 = extractelement <8 x i8> %0, i32 0
15+
; CHECK: %2 = bitcast <2 x i32> <i32 131586, i32 131586> to <8 x i8>
16+
; CHECK: %3 = extractelement <8 x i8> %2, i32 0
17+
; CHECK: %4 = add i8 %1, %3
18+
; CHECK: %5 = bitcast <2 x i32> <i32 65793, i32 65793> to <8 x i8>
19+
; CHECK: %6 = extractelement <8 x i8> %5, i32 1
20+
; CHECK: %7 = bitcast <2 x i32> <i32 131586, i32 131586> to <8 x i8>
21+
; CHECK: %8 = extractelement <8 x i8> %7, i32 1
22+
; CHECK: %9 = add i8 %6, %8
23+
; CHECK: %10 = bitcast <2 x i32> <i32 65793, i32 65793> to <8 x i8>
24+
; CHECK: %11 = extractelement <8 x i8> %10, i32 2
25+
; CHECK: %12 = bitcast <2 x i32> <i32 131586, i32 131586> to <8 x i8>
26+
; CHECK: %13 = extractelement <8 x i8> %12, i32 2
27+
; CHECK: %14 = add i8 %11, %13
28+
; CHECK: %15 = insertelement <3 x i8> undef, i8 %4, i32 0
29+
; CHECK: %16 = insertelement <3 x i8> %15, i8 %9, i32 1
30+
; CHECK: %17 = insertelement <3 x i8> %16, i8 %14, i32 2
31+
; CHECK: call void @llvm.dbg.value(metadata <3 x i8> %17, metadata !{{[0-9]+}}, metadata !DIExpression()), !dbg !{{[0-9]+}}
32+
}
33+
34+
; Function Attrs: nounwind readnone
35+
declare void @llvm.dbg.value(metadata, metadata, metadata) #2
36+
37+
attributes #0 = { nounwind ssp uwtable }
38+
attributes #2 = { nounwind readnone }
39+
attributes #3 = { nounwind }
40+
41+
!llvm.dbg.cu = !{!0}
42+
!llvm.module.flags = !{!13, !14, !15}
43+
!llvm.ident = !{!16}
44+
45+
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.7.0 (trunk 235110) (llvm/trunk 235108)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !2, globals: !2, imports: !2)
46+
!1 = !DIFile(filename: "t.c", directory: "/path/to/dir")
47+
!2 = !{}
48+
!4 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 3, type: !5, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !2)
49+
!5 = !DISubroutineType(types: !6)
50+
!6 = !{null}
51+
!7 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 2, type: !8, isLocal: true, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !11)
52+
!8 = !DISubroutineType(types: !9)
53+
!9 = !{null, !10}
54+
!10 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
55+
!11 = !{!12}
56+
!12 = !DILocalVariable(name: "a", arg: 1, scope: !7, file: !1, line: 2, type: !10)
57+
!13 = !{i32 2, !"Dwarf Version", i32 2}
58+
!14 = !{i32 2, !"Debug Info Version", i32 3}
59+
!15 = !{i32 1, !"PIC Level", i32 2}
60+
!16 = !{!"clang version 3.7.0 (trunk 235110) (llvm/trunk 235108)"}
61+
!17 = !DIExpression()
62+
!18 = !DILocation(line: 2, column: 52, scope: !7, inlinedAt: !19)
63+
!19 = distinct !DILocation(line: 4, column: 3, scope: !4)
64+
!20 = !DILocation(line: 6, column: 1, scope: !4)

0 commit comments

Comments
 (0)