forked from OSchip/llvm-project
[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:
parent
aa69cb7695
commit
95fedfab6c
|
@ -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 *
|
||||
|
|
|
@ -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()) &&
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
Loading…
Reference in New Issue