Reintroduce r320049, r320014 and r319894.
authorIgor Laevsky <igmyrj@gmail.com>
Wed, 13 Dec 2017 11:21:18 +0000 (11:21 +0000)
committerIgor Laevsky <igmyrj@gmail.com>
Wed, 13 Dec 2017 11:21:18 +0000 (11:21 +0000)
OpenGL issues should be fixed by now.

llvm-svn: 320568

llvm/include/llvm/Analysis/ConstantFolding.h
llvm/include/llvm/Analysis/InstructionSimplify.h
llvm/lib/Analysis/InstructionSimplify.cpp
llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
llvm/test/Transforms/InstCombine/out-of-bounds-indexes.ll
llvm/test/Transforms/InstCombine/pr28725.ll [new file with mode: 0644]
llvm/test/Transforms/InstCombine/vector_insertelt_shuffle.ll
llvm/test/Transforms/InstSimplify/insertelement.ll [new file with mode: 0644]
llvm/test/Transforms/InstSimplify/pr28725.ll

index cb314e3766cfe104c52422360d44e996f3636da8..6d4eef412525cd7b52fe8236be1baf31c7bd02cd 100644 (file)
@@ -102,6 +102,13 @@ Constant *ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val,
 Constant *ConstantFoldExtractValueInstruction(Constant *Agg,
                                               ArrayRef<unsigned> Idxs);
 
+/// \brief Attempt to constant fold an insertelement instruction with the
+/// specified operands and indices.  The constant result is returned if
+/// successful; if not, null is returned.
+Constant *ConstantFoldInsertElementInstruction(Constant *Val,
+                                               Constant *Elt,
+                                               Constant *Idx);
+
 /// \brief Attempt to constant fold an extractelement instruction with the
 /// specified operands and indices.  The constant result is returned if
 /// successful; if not, null is returned.
index be0f32ef444a490c5abd26263699d854b7d156ea..3932a2ec2498818159ee96927a83ae953cfd6fec 100644 (file)
@@ -161,6 +161,10 @@ Value *SimplifyGEPInst(Type *SrcTy, ArrayRef<Value *> Ops,
 Value *SimplifyInsertValueInst(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs,
                                const SimplifyQuery &Q);
 
+/// Given operands for an InsertElement, fold the result or return null.
+Value *SimplifyInsertElementInst(Value *Vec, Value *Elt, Value *Idx,
+                                 const SimplifyQuery &Q);
+
 /// Given operands for an ExtractValueInst, fold the result or return null.
 Value *SimplifyExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs,
                                 const SimplifyQuery &Q);
index 94de0c995d3ef7dc1fd33c5909f536dca306c3b3..09f516a8cb9bd4a2d73cd7e4302261c89213e9b5 100644 (file)
@@ -3827,6 +3827,28 @@ Value *llvm::SimplifyInsertValueInst(Value *Agg, Value *Val,
   return ::SimplifyInsertValueInst(Agg, Val, Idxs, Q, RecursionLimit);
 }
 
+Value *llvm::SimplifyInsertElementInst(Value *Vec, Value *Val, Value *Idx,
+                                       const SimplifyQuery &Q) {
+  // Try to constant fold.
+  auto *VecC = dyn_cast<Constant>(Vec);
+  auto *ValC = dyn_cast<Constant>(Val);
+  auto *IdxC = dyn_cast<Constant>(Idx);
+  if (VecC && ValC && IdxC)
+    return ConstantFoldInsertElementInstruction(VecC, ValC, IdxC);
+
+  // Fold into undef if index is out of bounds.
+  if (auto *CI = dyn_cast<ConstantInt>(Idx)) {
+    uint64_t NumElements = cast<VectorType>(Vec->getType())->getNumElements();
+
+    if (CI->uge(NumElements))
+      return UndefValue::get(Vec->getType());
+  }
+
+  // TODO: We should also fold if index is iteslf an undef.
+
+  return nullptr;
+}
+
 /// Given operands for an ExtractValueInst, see if we can fold the result.
 /// If not, this returns null.
 static Value *SimplifyExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs,
@@ -4700,6 +4722,12 @@ Value *llvm::SimplifyInstruction(Instruction *I, const SimplifyQuery &SQ,
                                      IV->getIndices(), Q);
     break;
   }
+  case Instruction::InsertElement: {
+    auto *IE = cast<InsertElementInst>(I);
+    Result = SimplifyInsertElementInst(IE->getOperand(0), IE->getOperand(1),
+                                       IE->getOperand(2), Q);
+    break;
+  }
   case Instruction::ExtractValue: {
     auto *EVI = cast<ExtractValueInst>(I);
     Result = SimplifyExtractValueInst(EVI->getAggregateOperand(),
index 6c99007475c12941cffe0b142656e27296ec3654..65a96b965227c57d9841e749cbdd4644254feacc 100644 (file)
@@ -781,6 +781,10 @@ Instruction *InstCombiner::visitInsertElementInst(InsertElementInst &IE) {
   Value *ScalarOp = IE.getOperand(1);
   Value *IdxOp    = IE.getOperand(2);
 
+  if (auto *V = SimplifyInsertElementInst(
+          VecOp, ScalarOp, IdxOp, SQ.getWithInstruction(&IE)))
+    return replaceInstUsesWith(IE, V);
+
   // Inserting an undef or into an undefined place, remove this.
   if (isa<UndefValue>(ScalarOp) || isa<UndefValue>(IdxOp))
     replaceInstUsesWith(IE, VecOp);
index a1887d27550baaa6e627eb836267995b0f5b4bab..02be57a4d152052bdf5e9b235435da6ae864b22d 100644 (file)
@@ -31,3 +31,11 @@ define i128 @test_non64bit(i128 %a) {
 }
 
 declare void @llvm.assume(i1)
+
+define <4 x double> @inselt_bad_index(<4 x double> %a) {
+; CHECK-LABEL: @inselt_bad_index(
+; CHECK-NEXT:    ret <4 x double> undef
+;
+  %I = insertelement <4 x double> %a, double 0.0, i64 4294967296
+  ret <4 x double> %I
+}
diff --git a/llvm/test/Transforms/InstCombine/pr28725.ll b/llvm/test/Transforms/InstCombine/pr28725.ll
new file mode 100644 (file)
index 0000000..ff9440d
--- /dev/null
@@ -0,0 +1,11 @@
+; RUN: opt -S -instcombine < %s | FileCheck %s
+%S = type { i16, i32 }
+
+define <2 x i16> @test1() {
+entry:
+  %b = insertelement <2 x i16> <i16 undef, i16 0>, i16 extractvalue (%S select (i1 icmp eq (i16 extractelement (<2 x i16> bitcast (<1 x i32> <i32 1> to <2 x i16>), i32 0), i16 0), %S zeroinitializer, %S { i16 0, i32 1 }), 0), i32 0
+  ret <2 x i16> %b
+}
+
+; CHECK-LABEL: @test1(
+; CHECK: ret <2 x i16> zeroinitializer
index c358509d690e9b19b47bbc6ec7d3f2383688b9bc..41c6370e48e9ae371df95ab8219c88004be60882 100644 (file)
@@ -54,10 +54,10 @@ define <4 x float> @bazz(<4 x float> %x, i32 %a) {
   ret <4 x float> %ins6
 }
 
+; Out of bounds index folds to undef
 define <4 x float> @bazzz(<4 x float> %x) {
 ; CHECK-LABEL: @bazzz(
-; CHECK-NEXT:    [[INS2:%.*]] = insertelement <4 x float> %x, float 2.000000e+00, i32 2
-; CHECK-NEXT:    ret <4 x float> [[INS2]]
+; CHECK-NEXT:   ret <4 x float> <float undef, float undef, float 2.000000e+00, float undef>
 ;
   %ins1 = insertelement<4 x float> %x, float 1.0, i32 5
   %ins2 = insertelement<4 x float> %ins1, float 2.0, i32 2
diff --git a/llvm/test/Transforms/InstSimplify/insertelement.ll b/llvm/test/Transforms/InstSimplify/insertelement.ll
new file mode 100644 (file)
index 0000000..3acd921
--- /dev/null
@@ -0,0 +1,25 @@
+; RUN: opt -S -instsimplify < %s | FileCheck %s
+
+define <4 x i32> @test1(<4 x i32> %A) {
+  %I = insertelement <4 x i32> %A, i32 5, i64 4294967296
+  ; CHECK: ret <4 x i32> undef
+  ret <4 x i32> %I
+}
+
+define <4 x i32> @test2(<4 x i32> %A) {
+  %I = insertelement <4 x i32> %A, i32 5, i64 4
+  ; CHECK: ret <4 x i32> undef
+  ret <4 x i32> %I
+}
+
+define <4 x i32> @test3(<4 x i32> %A) {
+  %I = insertelement <4 x i32> %A, i32 5, i64 1
+  ; CHECK: ret <4 x i32> %I
+  ret <4 x i32> %I
+}
+
+define <4 x i32> @test4(<4 x i32> %A) {
+  %I = insertelement <4 x i32> %A, i32 5, i128 100
+  ; CHECK: ret <4 x i32> undef
+  ret <4 x i32> %I
+}
index b85fc10b6c88576ba68fe8b30b8ffcd88c94a9f4..7ff0b90c65ddd1498f6fc313c2cd41bd1910aa0b 100644 (file)
@@ -1,6 +1,4 @@
 ; RUN: opt -S -instsimplify < %s | FileCheck %s
-target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
-target triple = "x86_64-pc-windows-msvc"
 %S = type { i16, i32 }
 
 define <2 x i16> @test1() {
@@ -9,5 +7,6 @@ entry:
   ret <2 x i16> %b
 }
 
+; InstCombine will be able to fold this into zeroinitializer
 ; CHECK-LABEL: @test1(
-; CHECK: ret <2 x i16> zeroinitializer
+; CHECK: ret <2 x i16> <i16 extractvalue (%S select (i1 icmp eq (i16 extractelement (<2 x i16> bitcast (<1 x i32> <i32 1> to <2 x i16>), i32 0), i16 0), %S zeroinitializer, %S { i16 0, i32 1 }), 0), i16 0>