Skip to content

Commit e714b98

Browse files
committed
[InstCombine] Check type compatibility in indexed load fold
This fold could use a rewrite to an offset-based implementation, but for now make sure it doesn't crash with opaque pointers.
1 parent 9474c30 commit e714b98

File tree

3 files changed

+62
-23
lines changed

3 files changed

+62
-23
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,14 @@ static bool isSignTest(ICmpInst::Predicate &Pred, const APInt &C) {
105105
///
106106
/// If AndCst is non-null, then the loaded value is masked with that constant
107107
/// before doing the comparison. This handles cases like "A[i]&4 == 0".
108-
Instruction *
109-
InstCombinerImpl::foldCmpLoadFromIndexedGlobal(GetElementPtrInst *GEP,
110-
GlobalVariable *GV, CmpInst &ICI,
111-
ConstantInt *AndCst) {
108+
Instruction *InstCombinerImpl::foldCmpLoadFromIndexedGlobal(
109+
LoadInst *LI, GetElementPtrInst *GEP, GlobalVariable *GV, CmpInst &ICI,
110+
ConstantInt *AndCst) {
111+
if (LI->isVolatile() || LI->getType() != GEP->getResultElementType() ||
112+
GV->getValueType() != GEP->getSourceElementType() ||
113+
!GV->isConstant() || !GV->hasDefinitiveInitializer())
114+
return nullptr;
115+
112116
Constant *Init = GV->getInitializer();
113117
if (!isa<ConstantArray>(Init) && !isa<ConstantDataArray>(Init))
114118
return nullptr;
@@ -1865,15 +1869,13 @@ Instruction *InstCombinerImpl::foldICmpAndConstant(ICmpInst &Cmp,
18651869
// Try to optimize things like "A[i] & 42 == 0" to index computations.
18661870
Value *X = And->getOperand(0);
18671871
Value *Y = And->getOperand(1);
1868-
if (auto *LI = dyn_cast<LoadInst>(X))
1869-
if (auto *GEP = dyn_cast<GetElementPtrInst>(LI->getOperand(0)))
1870-
if (auto *GV = dyn_cast<GlobalVariable>(GEP->getOperand(0)))
1871-
if (GV->isConstant() && GV->hasDefinitiveInitializer() &&
1872-
!LI->isVolatile() && isa<ConstantInt>(Y)) {
1873-
ConstantInt *C2 = cast<ConstantInt>(Y);
1874-
if (Instruction *Res = foldCmpLoadFromIndexedGlobal(GEP, GV, Cmp, C2))
1872+
if (auto *C2 = dyn_cast<ConstantInt>(Y))
1873+
if (auto *LI = dyn_cast<LoadInst>(X))
1874+
if (auto *GEP = dyn_cast<GetElementPtrInst>(LI->getOperand(0)))
1875+
if (auto *GV = dyn_cast<GlobalVariable>(GEP->getOperand(0)))
1876+
if (Instruction *Res =
1877+
foldCmpLoadFromIndexedGlobal(LI, GEP, GV, Cmp, C2))
18751878
return Res;
1876-
}
18771879

18781880
if (!Cmp.isEquality())
18791881
return nullptr;
@@ -3476,13 +3478,11 @@ Instruction *InstCombinerImpl::foldICmpInstWithConstantNotInt(ICmpInst &I) {
34763478
case Instruction::Load:
34773479
// Try to optimize things like "A[i] > 4" to index computations.
34783480
if (GetElementPtrInst *GEP =
3479-
dyn_cast<GetElementPtrInst>(LHSI->getOperand(0))) {
3481+
dyn_cast<GetElementPtrInst>(LHSI->getOperand(0)))
34803482
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(GEP->getOperand(0)))
3481-
if (GV->isConstant() && GV->hasDefinitiveInitializer() &&
3482-
!cast<LoadInst>(LHSI)->isVolatile())
3483-
if (Instruction *Res = foldCmpLoadFromIndexedGlobal(GEP, GV, I))
3484-
return Res;
3485-
}
3483+
if (Instruction *Res =
3484+
foldCmpLoadFromIndexedGlobal(cast<LoadInst>(LHSI), GEP, GV, I))
3485+
return Res;
34863486
break;
34873487
}
34883488

@@ -6632,10 +6632,9 @@ Instruction *InstCombinerImpl::visitFCmpInst(FCmpInst &I) {
66326632
case Instruction::Load:
66336633
if (auto *GEP = dyn_cast<GetElementPtrInst>(LHSI->getOperand(0)))
66346634
if (auto *GV = dyn_cast<GlobalVariable>(GEP->getOperand(0)))
6635-
if (GV->isConstant() && GV->hasDefinitiveInitializer() &&
6636-
!cast<LoadInst>(LHSI)->isVolatile())
6637-
if (Instruction *Res = foldCmpLoadFromIndexedGlobal(GEP, GV, I))
6638-
return Res;
6635+
if (Instruction *Res = foldCmpLoadFromIndexedGlobal(
6636+
cast<LoadInst>(LHSI), GEP, GV, I))
6637+
return Res;
66396638
break;
66406639
}
66416640
}

llvm/lib/Transforms/InstCombine/InstCombineInternal.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,8 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
652652
ICmpInst::Predicate Cond, Instruction &I);
653653
Instruction *foldAllocaCmp(ICmpInst &ICI, const AllocaInst *Alloca,
654654
const Value *Other);
655-
Instruction *foldCmpLoadFromIndexedGlobal(GetElementPtrInst *GEP,
655+
Instruction *foldCmpLoadFromIndexedGlobal(LoadInst *LI,
656+
GetElementPtrInst *GEP,
656657
GlobalVariable *GV, CmpInst &ICI,
657658
ConstantInt *AndCst = nullptr);
658659
Instruction *foldFCmpIntToFPConst(FCmpInst &I, Instruction *LHSI,

llvm/test/Transforms/InstCombine/opaque-ptr.ll

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,3 +305,42 @@ define i1 @cmp_gep_same_base_different_type(ptr %ptr, i64 %idx1, i64 %idx2) {
305305
%cmp = icmp ult ptr %gep1, %gep2
306306
ret i1 %cmp
307307
}
308+
309+
@ary = constant [4 x i8] [i8 1, i8 2, i8 3, i8 4]
310+
311+
define i1 @cmp_load_gep_global(i64 %idx) {
312+
; CHECK-LABEL: @cmp_load_gep_global(
313+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IDX:%.*]], 2
314+
; CHECK-NEXT: ret i1 [[CMP]]
315+
;
316+
%gep = getelementptr [4 x i8], ptr @ary, i64 0, i64 %idx
317+
%load = load i8, ptr %gep
318+
%cmp = icmp eq i8 %load, 3
319+
ret i1 %cmp
320+
}
321+
322+
define i1 @cmp_load_gep_global_different_load_type(i64 %idx) {
323+
; CHECK-LABEL: @cmp_load_gep_global_different_load_type(
324+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr [4 x i8], ptr @ary, i64 0, i64 [[IDX:%.*]]
325+
; CHECK-NEXT: [[LOAD:%.*]] = load i16, ptr [[GEP]], align 2
326+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[LOAD]], 3
327+
; CHECK-NEXT: ret i1 [[CMP]]
328+
;
329+
%gep = getelementptr [4 x i8], ptr @ary, i64 0, i64 %idx
330+
%load = load i16, ptr %gep
331+
%cmp = icmp eq i16 %load, 3
332+
ret i1 %cmp
333+
}
334+
335+
define i1 @cmp_load_gep_global_different_gep_type(i64 %idx) {
336+
; CHECK-LABEL: @cmp_load_gep_global_different_gep_type(
337+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr [4 x i16], ptr @ary, i64 0, i64 [[IDX:%.*]]
338+
; CHECK-NEXT: [[LOAD:%.*]] = load i16, ptr [[GEP]], align 2
339+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[LOAD]], 3
340+
; CHECK-NEXT: ret i1 [[CMP]]
341+
;
342+
%gep = getelementptr [4 x i16], ptr @ary, i64 0, i64 %idx
343+
%load = load i16, ptr %gep
344+
%cmp = icmp eq i16 %load, 3
345+
ret i1 %cmp
346+
}

0 commit comments

Comments
 (0)