[InstCombine] Handle non-canonical GEP index in indexed compare fold (PR55228)

Normally the index type will already be canonicalized here, but
this is not guaranteed depending on visitation order. The code
was already accounting for a potentially needed sext, but a trunc
may also be needed.

Add a ConstantExpr::getSExtOrTrunc() helper method to make this
simpler. This matches the corresponding IRBuilder method in behavior.

Fixes https://github.com/llvm/llvm-project/issues/55228.
This commit is contained in:
Nikita Popov 2022-05-02 17:52:02 +02:00
parent aa69cb7695
commit 95fedfab6c
4 changed files with 38 additions and 1 deletions

View File

@ -1160,6 +1160,11 @@ public:
Type *Ty ///< The type to trunc or bitcast C to
);
/// Create either an sext, trunc or nothing, depending on whether Ty is
/// wider, narrower or the same as C->getType(). This only works with
/// integer or vector of integer types.
static Constant *getSExtOrTrunc(Constant *C, Type *Ty);
/// Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant
/// expression.
static Constant *

View File

@ -2068,6 +2068,17 @@ Constant *ConstantExpr::getTruncOrBitCast(Constant *C, Type *Ty) {
return getTrunc(C, Ty);
}
Constant *ConstantExpr::getSExtOrTrunc(Constant *C, Type *Ty) {
assert(C->getType()->isIntOrIntVectorTy() && Ty->isIntOrIntVectorTy() &&
"Can only sign extend/truncate integers!");
Type *CTy = C->getType();
if (CTy->getScalarSizeInBits() < Ty->getScalarSizeInBits())
return getSExt(C, Ty);
if (CTy->getScalarSizeInBits() > Ty->getScalarSizeInBits())
return getTrunc(C, Ty);
return C;
}
Constant *ConstantExpr::getPointerCast(Constant *S, Type *Ty) {
assert(S->getType()->isPtrOrPtrVectorTy() && "Invalid cast");
assert((Ty->isIntOrIntVectorTy() || Ty->isPtrOrPtrVectorTy()) &&

View File

@ -759,7 +759,7 @@ getAsConstantIndexedAddress(Type *ElemTy, Value *V, const DataLayout &DL) {
V = GEP->getOperand(0);
Constant *GEPIndex = static_cast<Constant *>(GEP->getOperand(1));
Index = ConstantExpr::getAdd(
Index, ConstantExpr::getSExtOrBitCast(GEPIndex, IndexType));
Index, ConstantExpr::getSExtOrTrunc(GEPIndex, IndexType));
continue;
}
break;

View File

@ -0,0 +1,21 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -instcombine < %s | FileCheck %s
target datalayout = "p:8:8"
@g = external global i8
@c = constant ptr getelementptr inbounds (i8, ptr @g, i64 1)
define i1 @test(ptr %p) {
; CHECK-LABEL: @test(
; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[P:%.*]], getelementptr inbounds (i8, ptr @g, i8 1)
; CHECK-NEXT: ret i1 [[CMP]]
;
%alloca = alloca ptr
call void @llvm.memcpy.p0.p0.i32(ptr %alloca, ptr @c, i32 0, i1 false)
%load = load ptr, ptr %alloca
%cmp = icmp eq ptr %p, %load
ret i1 %cmp
}
declare void @llvm.memcpy.p0.p0.i32(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i32, i1 immarg)