From 8ae5787df5b23e1286c157ffcdd23578483f6ab2 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Mon, 20 Aug 2018 18:19:02 +0000 Subject: [PATCH] [ConstantFolding] improve folding of binops with vector undef operand A non-undef operand may still have undef constant elements, so we should always propagate the vector results per-lane. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@340194 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/IR/ConstantFold.cpp | 18 +++++++++--------- test/Analysis/ConstantFolding/vector-undef-elts.ll | 16 ++++++++-------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/lib/IR/ConstantFold.cpp b/lib/IR/ConstantFold.cpp index 90a8366d169..107975df1e7 100644 --- a/lib/IR/ConstantFold.cpp +++ b/lib/IR/ConstantFold.cpp @@ -916,13 +916,14 @@ Constant *llvm::ConstantFoldInsertValueInstruction(Constant *Agg, return ConstantVector::get(Result); } - -Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, - Constant *C1, Constant *C2) { +Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1, + Constant *C2) { assert(Instruction::isBinaryOp(Opcode) && "Non-binary instruction detected"); - // Handle UndefValue up front. - if (isa(C1) || isa(C2)) { + // Handle scalar UndefValue. Vectors are always evaluated per element. + bool HasScalarUndef = !C1->getType()->isVectorTy() && + (isa(C1) || isa(C2)); + if (HasScalarUndef) { switch (static_cast(Opcode)) { case Instruction::Xor: if (isa(C1) && isa(C2)) @@ -1024,9 +1025,8 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, } } - // At this point neither constant should be an UndefValue. - assert(!isa(C1) && !isa(C2) && - "Unexpected UndefValue"); + // Neither constant should be UndefValue, unless these are vector constants. + assert(!HasScalarUndef && "Unexpected UndefValue"); // Handle simplifications when the RHS is a constant int. if (ConstantInt *CI2 = dyn_cast(C2)) { @@ -1218,7 +1218,7 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, } } } else if (VectorType *VTy = dyn_cast(C1->getType())) { - // Perform elementwise folding. + // Fold each element and create a vector constant from those constants. SmallVector Result; Type *Ty = IntegerType::get(VTy->getContext(), 32); for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) { diff --git a/test/Analysis/ConstantFolding/vector-undef-elts.ll b/test/Analysis/ConstantFolding/vector-undef-elts.ll index c590dd3cdf7..f6969d83fce 100644 --- a/test/Analysis/ConstantFolding/vector-undef-elts.ll +++ b/test/Analysis/ConstantFolding/vector-undef-elts.ll @@ -1,11 +1,11 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -constprop -S -o - | FileCheck %s -; FIXME: When both operands are undef in a lane, that lane should produce an undef result. +; When both operands are undef in a lane, that lane should produce an undef result. define <3 x i8> @shl() { ; CHECK-LABEL: @shl( -; CHECK-NEXT: ret <3 x i8> zeroinitializer +; CHECK-NEXT: ret <3 x i8> ; %c = shl <3 x i8> undef, ret <3 x i8> %c @@ -13,7 +13,7 @@ define <3 x i8> @shl() { define <3 x i8> @and() { ; CHECK-LABEL: @and( -; CHECK-NEXT: ret <3 x i8> zeroinitializer +; CHECK-NEXT: ret <3 x i8> ; %c = and <3 x i8> , undef ret <3 x i8> %c @@ -21,7 +21,7 @@ define <3 x i8> @and() { define <3 x i8> @and_commute() { ; CHECK-LABEL: @and_commute( -; CHECK-NEXT: ret <3 x i8> zeroinitializer +; CHECK-NEXT: ret <3 x i8> ; %c = and <3 x i8> undef, ret <3 x i8> %c @@ -29,7 +29,7 @@ define <3 x i8> @and_commute() { define <3 x i8> @or() { ; CHECK-LABEL: @or( -; CHECK-NEXT: ret <3 x i8> +; CHECK-NEXT: ret <3 x i8> ; %c = or <3 x i8> , undef ret <3 x i8> %c @@ -37,7 +37,7 @@ define <3 x i8> @or() { define <3 x i8> @or_commute() { ; CHECK-LABEL: @or_commute( -; CHECK-NEXT: ret <3 x i8> +; CHECK-NEXT: ret <3 x i8> ; %c = or <3 x i8> undef, ret <3 x i8> %c @@ -45,7 +45,7 @@ define <3 x i8> @or_commute() { define <3 x float> @fadd() { ; CHECK-LABEL: @fadd( -; CHECK-NEXT: ret <3 x float> +; CHECK-NEXT: ret <3 x float> ; %c = fadd <3 x float> , undef ret <3 x float> %c @@ -53,7 +53,7 @@ define <3 x float> @fadd() { define <3 x float> @fadd_commute() { ; CHECK-LABEL: @fadd_commute( -; CHECK-NEXT: ret <3 x float> +; CHECK-NEXT: ret <3 x float> ; %c = fadd <3 x float> undef, ret <3 x float> %c -- 2.11.0