diff options
-rw-r--r-- | lib/Transforms/NaCl/ExpandStructRegs.cpp | 36 | ||||
-rw-r--r-- | test/Transforms/NaCl/expand-struct-regs.ll | 11 |
2 files changed, 47 insertions, 0 deletions
diff --git a/lib/Transforms/NaCl/ExpandStructRegs.cpp b/lib/Transforms/NaCl/ExpandStructRegs.cpp index ac83d33e78..5c11a76c8b 100644 --- a/lib/Transforms/NaCl/ExpandStructRegs.cpp +++ b/lib/Transforms/NaCl/ExpandStructRegs.cpp @@ -97,6 +97,37 @@ static void SplitUpPHINode(PHINode *Phi) { Phi->eraseFromParent(); } +static void SplitUpSelect(SelectInst *Select) { + StructType *STy = cast<StructType>(Select->getType()); + Value *NewStruct = UndefValue::get(STy); + + // Create a separate SelectInst for each struct field. + for (unsigned Index = 0; Index < STy->getNumElements(); ++Index) { + SmallVector<unsigned, 1> EVIndexes; + EVIndexes.push_back(Index); + + Value *TrueVal = CopyDebug( + ExtractValueInst::Create(Select->getTrueValue(), EVIndexes, + Select->getName() + ".extract", Select), + Select); + Value *FalseVal = CopyDebug( + ExtractValueInst::Create(Select->getFalseValue(), EVIndexes, + Select->getName() + ".extract", Select), + Select); + Value *NewSelect = CopyDebug( + SelectInst::Create(Select->getCondition(), TrueVal, FalseVal, + Select->getName() + ".index", Select), Select); + + // Reconstruct the original struct value. + NewStruct = CopyDebug( + InsertValueInst::Create(NewStruct, NewSelect, EVIndexes, + Select->getName() + ".insert", Select), + Select); + } + Select->replaceAllUsesWith(NewStruct); + Select->eraseFromParent(); +} + template <class InstType> static void ProcessLoadOrStoreAttrs(InstType *Dest, InstType *Src) { CopyDebug(Dest, Src); @@ -215,6 +246,11 @@ bool ExpandStructRegs::runOnFunction(Function &Func) { SplitUpPHINode(Phi); Changed = true; } + } else if (SelectInst *Select = dyn_cast<SelectInst>(Inst)) { + if (Select->getType()->isStructTy()) { + SplitUpSelect(Select); + Changed = true; + } } } } diff --git a/test/Transforms/NaCl/expand-struct-regs.ll b/test/Transforms/NaCl/expand-struct-regs.ll index 8291ec5069..0cc2c6db85 100644 --- a/test/Transforms/NaCl/expand-struct-regs.ll +++ b/test/Transforms/NaCl/expand-struct-regs.ll @@ -92,6 +92,17 @@ bb: ; CHECK-NEXT: %phi.index{{.*}} = phi i32 [ %val.field{{.*}}, %entry ], [ %val.field{{.*}}, %entry ] +define void @struct_select_inst(i1 %cond, %struct* %ptr1, %struct* %ptr2) { + %val1 = load %struct* %ptr1 + %val2 = load %struct* %ptr2 + %select = select i1 %cond, %struct %val1, %struct %val2 + ret void +} +; CHECK: define void @struct_select_inst +; CHECK: %select.index{{.*}} = select i1 %cond, i8 %val1.field{{.*}}, i8 %val2.field{{.*}} +; CHECK-NEXT: %select.index{{.*}} = select i1 %cond, i32 %val1.field{{.*}}, i32 %val2.field{{.*}} + + define void @insert_and_extract(i8* %out0, i32* %out1) { %temp = insertvalue %struct undef, i8 100, 0 %sval = insertvalue %struct %temp, i32 200, 1 |