[llvm] r340194 - [ConstantFolding] improve folding of binops with vector undef operand

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 20 11:19:02 PDT 2018


Author: spatel
Date: Mon Aug 20 11:19:02 2018
New Revision: 340194

URL: http://llvm.org/viewvc/llvm-project?rev=340194&view=rev
Log:
[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.

Modified:
    llvm/trunk/lib/IR/ConstantFold.cpp
    llvm/trunk/test/Analysis/ConstantFolding/vector-undef-elts.ll

Modified: llvm/trunk/lib/IR/ConstantFold.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/ConstantFold.cpp?rev=340194&r1=340193&r2=340194&view=diff
==============================================================================
--- llvm/trunk/lib/IR/ConstantFold.cpp (original)
+++ llvm/trunk/lib/IR/ConstantFold.cpp Mon Aug 20 11:19:02 2018
@@ -916,13 +916,14 @@ Constant *llvm::ConstantFoldInsertValueI
   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<UndefValue>(C1) || isa<UndefValue>(C2)) {
+  // Handle scalar UndefValue. Vectors are always evaluated per element.
+  bool HasScalarUndef = !C1->getType()->isVectorTy() &&
+                        (isa<UndefValue>(C1) || isa<UndefValue>(C2));
+  if (HasScalarUndef) {
     switch (static_cast<Instruction::BinaryOps>(Opcode)) {
     case Instruction::Xor:
       if (isa<UndefValue>(C1) && isa<UndefValue>(C2))
@@ -1024,9 +1025,8 @@ Constant *llvm::ConstantFoldBinaryInstru
     }
   }
 
-  // At this point neither constant should be an UndefValue.
-  assert(!isa<UndefValue>(C1) && !isa<UndefValue>(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<ConstantInt>(C2)) {
@@ -1218,7 +1218,7 @@ Constant *llvm::ConstantFoldBinaryInstru
       }
     }
   } else if (VectorType *VTy = dyn_cast<VectorType>(C1->getType())) {
-    // Perform elementwise folding.
+    // Fold each element and create a vector constant from those constants.
     SmallVector<Constant*, 16> Result;
     Type *Ty = IntegerType::get(VTy->getContext(), 32);
     for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) {

Modified: llvm/trunk/test/Analysis/ConstantFolding/vector-undef-elts.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ConstantFolding/vector-undef-elts.ll?rev=340194&r1=340193&r2=340194&view=diff
==============================================================================
--- llvm/trunk/test/Analysis/ConstantFolding/vector-undef-elts.ll (original)
+++ llvm/trunk/test/Analysis/ConstantFolding/vector-undef-elts.ll Mon Aug 20 11:19:02 2018
@@ -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> <i8 undef, i8 0, i8 0>
 ;
   %c = shl <3 x i8> undef, <i8 undef, i8 4, i8 1>
   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> <i8 undef, i8 0, i8 undef>
 ;
   %c = and <3 x i8> <i8 undef, i8 42, i8 undef>, 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> <i8 0, i8 0, i8 undef>
 ;
   %c = and <3 x i8> undef, <i8 -42, i8 42, 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> <i8 -1, i8 -1, i8 -1>
+; CHECK-NEXT:    ret <3 x i8> <i8 undef, i8 -1, i8 undef>
 ;
   %c = or <3 x i8> <i8 undef, i8 42, i8 undef>, 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> <i8 -1, i8 -1, i8 -1>
+; CHECK-NEXT:    ret <3 x i8> <i8 -1, i8 -1, i8 undef>
 ;
   %c = or <3 x i8> undef, <i8 -42, i8 42, 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> <float 0x7FF8000000000000, float 0x7FF8000000000000, float 0x7FF8000000000000>
+; CHECK-NEXT:    ret <3 x float> <float undef, float 0x7FF8000000000000, float undef>
 ;
   %c = fadd <3 x float> <float undef, float 42.0, float undef>, 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> <float 0x7FF8000000000000, float 0x7FF8000000000000, float 0x7FF8000000000000>
+; CHECK-NEXT:    ret <3 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000, float undef>
 ;
   %c = fadd <3 x float> undef, <float -42.0, float 42.0, float undef>
   ret <3 x float> %c




More information about the llvm-commits mailing list