Skip to content

Commit 6a36c64

Browse files
author
Volkan Keles
committedMay 19, 2017
[GlobalISel] IRTranslator: Translate ConstantStruct
Reviewers: qcolombet, ab, t.p.northover, aditya_nandakumar, dsanders Reviewed By: qcolombet Subscribers: rovka, kristof.beyls, javed.absar, igorb, llvm-commits Differential Revision: https://reviews.llvm.org/D33317 llvm-svn: 303412
1 parent 796d5ff commit 6a36c64

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed
 

‎llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp

+26
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,15 @@ bool IRTranslator::translateExtractValue(const User &U,
340340
Type *Int32Ty = Type::getInt32Ty(U.getContext());
341341
SmallVector<Value *, 1> Indices;
342342

343+
// If Src is a single element ConstantStruct, translate extractvalue
344+
// to that element to avoid inserting a cast instruction.
345+
if (auto CS = dyn_cast<ConstantStruct>(Src))
346+
if (CS->getNumOperands() == 1) {
347+
unsigned Res = getOrCreateVReg(*CS->getOperand(0));
348+
ValToVReg[&U] = Res;
349+
return true;
350+
}
351+
343352
// getIndexedOffsetInType is designed for GEPs, so the first index is the
344353
// usual array element rather than looking into the actual aggregate.
345354
Indices.push_back(ConstantInt::get(Int32Ty, 0));
@@ -1108,6 +1117,23 @@ bool IRTranslator::translate(const Constant &C, unsigned Reg) {
11081117
default:
11091118
return false;
11101119
}
1120+
} else if (auto CS = dyn_cast<ConstantStruct>(&C)) {
1121+
// Return the element if it is a single element ConstantStruct.
1122+
if (CS->getNumOperands() == 1) {
1123+
unsigned EltReg = getOrCreateVReg(*CS->getOperand(0));
1124+
EntryBuilder.buildCast(Reg, EltReg);
1125+
return true;
1126+
}
1127+
SmallVector<unsigned, 4> Ops;
1128+
SmallVector<uint64_t, 4> Indices;
1129+
uint64_t Offset = 0;
1130+
for (unsigned i = 0; i < CS->getNumOperands(); ++i) {
1131+
unsigned OpReg = getOrCreateVReg(*CS->getOperand(i));
1132+
Ops.push_back(OpReg);
1133+
Indices.push_back(Offset);
1134+
Offset += MRI->getType(OpReg).getSizeInBits();
1135+
}
1136+
EntryBuilder.buildSequence(Reg, Ops, Indices);
11111137
} else if (auto CV = dyn_cast<ConstantVector>(&C)) {
11121138
if (CV->getNumOperands() == 1)
11131139
return translate(*CV->getOperand(0), Reg);

‎llvm/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll

+30
Original file line numberDiff line numberDiff line change
@@ -699,3 +699,33 @@ define i32 @test_shufflevector_v4s32_v2s32(i32 %arg1, i32 %arg2, i32 %arg3, i32
699699
%res = extractelement <2 x i32> %shuffle, i32 0
700700
ret i32 %res
701701
}
702+
703+
%struct.v2s32 = type { <2 x i32> }
704+
705+
define i32 @test_constantstruct_v2s32() {
706+
; CHECK-LABEL: name: test_constantstruct_v2s32
707+
; CHECK: [[C1:%[0-9]+]](s32) = G_CONSTANT i32 1
708+
; CHECK: [[C2:%[0-9]+]](s32) = G_CONSTANT i32 2
709+
; CHECK: [[VEC:%[0-9]+]](<2 x s32>) = G_MERGE_VALUES [[C1]](s32), [[C2]](s32)
710+
; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>)
711+
%vec = extractvalue %struct.v2s32 {<2 x i32><i32 1, i32 2>}, 0
712+
%elt = extractelement <2 x i32> %vec, i32 0
713+
ret i32 %elt
714+
}
715+
716+
%struct.v2s32.s32.s32 = type { <2 x i32>, i32, i32 }
717+
718+
define i32 @test_constantstruct_v2s32_s32_s32() {
719+
; CHECK-LABEL: name: test_constantstruct_v2s32_s32_s32
720+
; CHECK: [[C1:%[0-9]+]](s32) = G_CONSTANT i32 1
721+
; CHECK: [[C2:%[0-9]+]](s32) = G_CONSTANT i32 2
722+
; CHECK: [[VEC:%[0-9]+]](<2 x s32>) = G_MERGE_VALUES [[C1]](s32), [[C2]](s32)
723+
; CHECK: [[C3:%[0-9]+]](s32) = G_CONSTANT i32 3
724+
; CHECK: [[C4:%[0-9]+]](s32) = G_CONSTANT i32 4
725+
; CHECK: [[CS:%[0-9]+]](s128) = G_SEQUENCE [[VEC]](<2 x s32>), 0, [[C3]](s32), 64, [[C4]](s32), 96
726+
; CHECK: [[EXT:%[0-9]+]](<2 x s32>) = G_EXTRACT [[CS]](s128), 0
727+
; CHECK: G_EXTRACT_VECTOR_ELT [[EXT]](<2 x s32>)
728+
%vec = extractvalue %struct.v2s32.s32.s32 {<2 x i32><i32 1, i32 2>, i32 3, i32 4}, 0
729+
%elt = extractelement <2 x i32> %vec, i32 0
730+
ret i32 %elt
731+
}

0 commit comments

Comments
 (0)
Failed to load comments.