[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