[llvm] r221069 - InstCombine: Don't assume that m_ZExt matches an Instruction

David Majnemer david.majnemer at gmail.com
Sat Nov 1 16:46:05 PDT 2014


Author: majnemer
Date: Sat Nov  1 18:46:05 2014
New Revision: 221069

URL: http://llvm.org/viewvc/llvm-project?rev=221069&view=rev
Log:
InstCombine: Don't assume that m_ZExt matches an Instruction

m_ZExt might bind against a ConstantExpr instead of an Instruction.
Assuming this, using cast<Instruction>, results in InstCombine crashing.

Instead, introduce ZExtOperator to bridge both Instruction and
ConstantExpr ZExts.

This fixes PR21445.

Modified:
    llvm/trunk/include/llvm/IR/Operator.h
    llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
    llvm/trunk/test/Transforms/InstCombine/overflow-mul.ll

Modified: llvm/trunk/include/llvm/IR/Operator.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Operator.h?rev=221069&r1=221068&r2=221069&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Operator.h (original)
+++ llvm/trunk/include/llvm/IR/Operator.h Sat Nov  1 18:46:05 2014
@@ -358,6 +358,8 @@ class LShrOperator
 };
 
 
+class ZExtOperator : public ConcreteOperator<Operator, Instruction::ZExt> {};
+
 
 class GEPOperator
   : public ConcreteOperator<Operator, Instruction::GetElementPtr> {

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=221069&r1=221068&r2=221069&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Sat Nov  1 18:46:05 2014
@@ -2160,8 +2160,8 @@ static Instruction *ProcessUMulZExtIdiom
   Instruction *MulInstr = cast<Instruction>(MulVal);
   assert(MulInstr->getOpcode() == Instruction::Mul);
 
-  Instruction *LHS = cast<Instruction>(MulInstr->getOperand(0)),
-              *RHS = cast<Instruction>(MulInstr->getOperand(1));
+  auto *LHS = cast<ZExtOperator>(MulInstr->getOperand(0)),
+       *RHS = cast<ZExtOperator>(MulInstr->getOperand(1));
   assert(LHS->getOpcode() == Instruction::ZExt);
   assert(RHS->getOpcode() == Instruction::ZExt);
   Value *A = LHS->getOperand(0), *B = RHS->getOperand(0);

Modified: llvm/trunk/test/Transforms/InstCombine/overflow-mul.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/overflow-mul.ll?rev=221069&r1=221068&r2=221069&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/overflow-mul.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/overflow-mul.ll Sat Nov  1 18:46:05 2014
@@ -173,3 +173,16 @@ define <4 x i32> @pr20113(<4 x i16> %a,
   %vcgez.i = sext <4 x i1> %tmp to <4 x i32>
   ret <4 x i32> %vcgez.i
 }
+
+ at pr21445_data = external global i32
+define i1 @pr21445(i8 %a) {
+; CHECK-LABEL: @pr21445(
+; CHECK-NEXT:  %[[umul:.*]] = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 %a, i8 ptrtoint (i32* @pr21445_data to i8))
+; CHECK-NEXT:  %[[cmp:.*]] = extractvalue { i8, i1 } %[[umul]], 1
+; CHECK-NEXT:  ret i1 %[[cmp]]
+  %ext = zext i8 %a to i32
+  %mul = mul i32 %ext, zext (i8 ptrtoint (i32* @pr21445_data to i8) to i32)
+  %and = and i32 %mul, 255
+  %cmp = icmp ne i32 %mul, %and
+  ret i1 %cmp
+}





More information about the llvm-commits mailing list