From 3b637f628162677a44dcf0622a8ec65c80aa76eb Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Sun, 9 Jul 2017 16:01:04 +0000 Subject: [PATCH] Handle ConstantExpr correctly in SelectionDAGBuilder This change fixes a bug in SelectionDAGBuilder::visitInsertValue and SelectionDAGBuilder::visitExtractValue where constant expressions (InsertValueConstantExpr and ExtractValueConstantExpr) would be treated as non-constant instructions (InsertValueInst and ExtractValueInst). This bug resulted in an incorrect memory access, which manifested as an assertion failure in SDValue::SDValue. Fixes PR#33094. Submitted on behalf of @Praetonus (Benoit Vey) Differential Revision: https://reviews.llvm.org/D34538 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307502 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../SelectionDAG/SelectionDAGBuilder.cpp | 20 +++++++++++++++---- .../SelectionDAG/SelectionDAGBuilder.h | 6 ++---- test/CodeGen/Generic/pr33094.ll | 18 +++++++++++++++++ 3 files changed, 36 insertions(+), 8 deletions(-) create mode 100644 test/CodeGen/Generic/pr33094.ll diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index a62506089a9..dbec2796ed7 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -3220,7 +3220,13 @@ void SelectionDAGBuilder::visitShuffleVector(const User &I) { setValue(&I, DAG.getBuildVector(VT, DL, Ops)); } -void SelectionDAGBuilder::visitInsertValue(const InsertValueInst &I) { +void SelectionDAGBuilder::visitInsertValue(const User &I) { + ArrayRef Indices; + if (const InsertValueInst *IV = dyn_cast(&I)) + Indices = IV->getIndices(); + else + Indices = cast(&I)->getIndices(); + const Value *Op0 = I.getOperand(0); const Value *Op1 = I.getOperand(1); Type *AggTy = I.getType(); @@ -3228,7 +3234,7 @@ void SelectionDAGBuilder::visitInsertValue(const InsertValueInst &I) { bool IntoUndef = isa(Op0); bool FromUndef = isa(Op1); - unsigned LinearIndex = ComputeLinearIndex(AggTy, I.getIndices()); + unsigned LinearIndex = ComputeLinearIndex(AggTy, Indices); const TargetLowering &TLI = DAG.getTargetLoweringInfo(); SmallVector AggValueVTs; @@ -3268,13 +3274,19 @@ void SelectionDAGBuilder::visitInsertValue(const InsertValueInst &I) { DAG.getVTList(AggValueVTs), Values)); } -void SelectionDAGBuilder::visitExtractValue(const ExtractValueInst &I) { +void SelectionDAGBuilder::visitExtractValue(const User &I) { + ArrayRef Indices; + if (const ExtractValueInst *EV = dyn_cast(&I)) + Indices = EV->getIndices(); + else + Indices = cast(&I)->getIndices(); + const Value *Op0 = I.getOperand(0); Type *AggTy = Op0->getType(); Type *ValTy = I.getType(); bool OutOfUndef = isa(Op0); - unsigned LinearIndex = ComputeLinearIndex(AggTy, I.getIndices()); + unsigned LinearIndex = ComputeLinearIndex(AggTy, Indices); const TargetLowering &TLI = DAG.getTargetLoweringInfo(); SmallVector ValValueVTs; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h index 431d52b4b9b..ac1d6aae65a 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -38,7 +38,6 @@ class BranchInst; class CallInst; class DbgValueInst; class ExtractElementInst; -class ExtractValueInst; class FCmpInst; class FPExtInst; class FPToSIInst; @@ -53,7 +52,6 @@ class IntToPtrInst; class IndirectBrInst; class InvokeInst; class InsertElementInst; -class InsertValueInst; class Instruction; class LoadInst; class MachineBasicBlock; @@ -859,8 +857,8 @@ private: void visitInsertElement(const User &I); void visitShuffleVector(const User &I); - void visitExtractValue(const ExtractValueInst &I); - void visitInsertValue(const InsertValueInst &I); + void visitExtractValue(const User &I); + void visitInsertValue(const User &I); void visitLandingPad(const LandingPadInst &I); void visitGetElementPtr(const User &I); diff --git a/test/CodeGen/Generic/pr33094.ll b/test/CodeGen/Generic/pr33094.ll new file mode 100644 index 00000000000..afa464f63f6 --- /dev/null +++ b/test/CodeGen/Generic/pr33094.ll @@ -0,0 +1,18 @@ +; RUN: llc < %s + +; PR33094 +; Make sure that a constant extractvalue doesn't cause a crash in +; SelectionDAGBuilder::visitExtractValue. + +%A = type {} +%B = type {} +%Tuple = type { i64 } + +@A_Inst = global %A zeroinitializer +@B_Inst = global %B zeroinitializer + +define i64 @foo() { + ret i64 extractvalue (%Tuple select (i1 icmp eq + (%B* bitcast (%A* @A_Inst to %B*), %B* @B_Inst), + %Tuple { i64 33 }, %Tuple { i64 42 }), 0) +}