forked from OSchip/llvm-project
[InstCombine] Require equal source element type in icmp of gep fold
Without opaque pointers, this is implicitly enforced. This previously resulted in a miscompile.
This commit is contained in:
parent
c28b0b9d18
commit
3571bdb4f3
|
@ -950,7 +950,8 @@ Instruction *InstCombinerImpl::foldGEPICmp(GEPOperator *GEPLHS, Value *RHS,
|
||||||
return foldGEPICmp(GEPLHS, GEPRHS->getOperand(0), Cond, I);
|
return foldGEPICmp(GEPLHS, GEPRHS->getOperand(0), Cond, I);
|
||||||
|
|
||||||
bool GEPsInBounds = GEPLHS->isInBounds() && GEPRHS->isInBounds();
|
bool GEPsInBounds = GEPLHS->isInBounds() && GEPRHS->isInBounds();
|
||||||
if (GEPLHS->getNumOperands() == GEPRHS->getNumOperands()) {
|
if (GEPLHS->getNumOperands() == GEPRHS->getNumOperands() &&
|
||||||
|
GEPLHS->getSourceElementType() == GEPRHS->getSourceElementType()) {
|
||||||
// If the GEPs only differ by one index, compare it.
|
// If the GEPs only differ by one index, compare it.
|
||||||
unsigned NumDifferences = 0; // Keep track of # differences.
|
unsigned NumDifferences = 0; // Keep track of # differences.
|
||||||
unsigned DiffOperand = 0; // The operand that differs.
|
unsigned DiffOperand = 0; // The operand that differs.
|
||||||
|
|
|
@ -281,3 +281,27 @@ define ptr addrspace(1) @gep_of_addrspace_cast(ptr %ptr) {
|
||||||
%gep = getelementptr inbounds i32, ptr addrspace(1) %cast1, i64 1
|
%gep = getelementptr inbounds i32, ptr addrspace(1) %cast1, i64 1
|
||||||
ret ptr addrspace(1) %gep
|
ret ptr addrspace(1) %gep
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define i1 @cmp_gep_same_base_same_type(ptr %ptr, i64 %idx1, i64 %idx2) {
|
||||||
|
; CHECK-LABEL: @cmp_gep_same_base_same_type(
|
||||||
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[IDX1:%.*]], [[IDX2:%.*]]
|
||||||
|
; CHECK-NEXT: ret i1 [[CMP]]
|
||||||
|
;
|
||||||
|
%gep1 = getelementptr inbounds i32, ptr %ptr, i64 %idx1
|
||||||
|
%gep2 = getelementptr inbounds i32, ptr %ptr, i64 %idx2
|
||||||
|
%cmp = icmp ult ptr %gep1, %gep2
|
||||||
|
ret i1 %cmp
|
||||||
|
}
|
||||||
|
|
||||||
|
define i1 @cmp_gep_same_base_different_type(ptr %ptr, i64 %idx1, i64 %idx2) {
|
||||||
|
; CHECK-LABEL: @cmp_gep_same_base_different_type(
|
||||||
|
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[IDX1:%.*]], 2
|
||||||
|
; CHECK-NEXT: [[GEP2_IDX:%.*]] = shl nsw i64 [[IDX2:%.*]], 3
|
||||||
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[GEP1_IDX]], [[GEP2_IDX]]
|
||||||
|
; CHECK-NEXT: ret i1 [[CMP]]
|
||||||
|
;
|
||||||
|
%gep1 = getelementptr inbounds i32, ptr %ptr, i64 %idx1
|
||||||
|
%gep2 = getelementptr inbounds i64, ptr %ptr, i64 %idx2
|
||||||
|
%cmp = icmp ult ptr %gep1, %gep2
|
||||||
|
ret i1 %cmp
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue