From bdda115e190092abac5a2dc6a2ed8c19e06a4156 Mon Sep 17 00:00:00 2001 From: Daniel Neilson Date: Mon, 5 Mar 2018 18:05:51 +0000 Subject: [PATCH] [InstCombine] Don't blow up in foldICmpWithCastAndCast on vector icmp instructions. Summary: Presently, InstCombiner::foldICmpWithCastAndCast() implicitly assumes that it is only invoked with icmp instructions of integer type. If that assumption is broken, and it is called with an icmp of vector type, then it fails (asserts/crashes). This patch addresses the deficiency. It allows it to simplify icmp (ptrtoint x), (ptrtoint/c) of vector type into a compare of the inputs, much as is done when the type is integer. Reviewers: apilipenko, fedor.sergeev, mkazantsev, anna Reviewed By: anna Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D44063 llvm-svn: 326730 --- .../Transforms/InstCombine/InstCombineCompares.cpp | 9 ++++++++- llvm/test/Transforms/InstCombine/icmp.ll | 12 ++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 6d053d162b96..0cd72bce45d5 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -3408,8 +3408,15 @@ Instruction *InstCombiner::foldICmpWithCastAndCast(ICmpInst &ICmp) { // Turn icmp (ptrtoint x), (ptrtoint/c) into a compare of the input if the // integer type is the same size as the pointer type. + const auto& CompatibleSizes = [&](Type* SrcTy, Type* DestTy) -> bool { + if (isa(SrcTy)) { + SrcTy = cast(SrcTy)->getElementType(); + DestTy = cast(DestTy)->getElementType(); + } + return DL.getPointerTypeSizeInBits(SrcTy) == DestTy->getIntegerBitWidth(); + }; if (LHSCI->getOpcode() == Instruction::PtrToInt && - DL.getPointerTypeSizeInBits(SrcTy) == DestTy->getIntegerBitWidth()) { + CompatibleSizes(SrcTy, DestTy)) { Value *RHSOp = nullptr; if (auto *RHSC = dyn_cast(ICmp.getOperand(1))) { Value *RHSCIOp = RHSC->getOperand(0); diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll index 26d21fb15a05..22f5ba5117b4 100644 --- a/llvm/test/Transforms/InstCombine/icmp.ll +++ b/llvm/test/Transforms/InstCombine/icmp.ll @@ -3302,3 +3302,15 @@ define i1 @PR35794(i32* %a) { ret i1 %cmp } +; Don't crash by assuming the compared values are integers. +define <2 x i1> @PR36583(<2 x i8*>) { +; CHECK-LABEL: @PR36583( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[RES:%.*]] = icmp eq <2 x i8*> %0, zeroinitializer +; CHECK-NEXT: ret <2 x i1> [[RES]] +; +entry: + %cast = ptrtoint <2 x i8*> %0 to <2 x i64> + %res = icmp eq <2 x i64> %cast, zeroinitializer + ret <2 x i1> %res +}