CRHS->getPointerOperand(), Q))
return C;
- if (GetElementPtrInst *GLHS = dyn_cast<GetElementPtrInst>(LHS)) {
- if (GEPOperator *GRHS = dyn_cast<GEPOperator>(RHS)) {
- if (GLHS->getPointerOperand() == GRHS->getPointerOperand() &&
- GLHS->hasAllConstantIndices() && GRHS->hasAllConstantIndices() &&
- (ICmpInst::isEquality(Pred) ||
- (GLHS->isInBounds() && GRHS->isInBounds() &&
- Pred == ICmpInst::getSignedPredicate(Pred)))) {
- // The bases are equal and the indices are constant. Build a constant
- // expression GEP with the same indices and a null base pointer to see
- // what constant folding can make out of it.
- Constant *Null = Constant::getNullValue(GLHS->getPointerOperandType());
- SmallVector<Value *, 4> IndicesLHS(GLHS->indices());
- Constant *NewLHS = ConstantExpr::getGetElementPtr(
- GLHS->getSourceElementType(), Null, IndicesLHS);
-
- SmallVector<Value *, 4> IndicesRHS(GRHS->indices());
- Constant *NewRHS = ConstantExpr::getGetElementPtr(
- GLHS->getSourceElementType(), Null, IndicesRHS);
- Constant *NewICmp = ConstantExpr::getICmp(Pred, NewLHS, NewRHS);
- return ConstantFoldConstant(NewICmp, Q.DL);
- }
- }
- }
-
// If the comparison is with the result of a select instruction, check whether
// comparing with either branch of the select always yields the same value.
if (isa<SelectInst>(LHS) || isa<SelectInst>(RHS))
; Don't transform non-inbounds GEPs.
}
+; Negative test: GEP inbounds may cross sign boundary.
define i1 @test62(i8* %a) {
; CHECK-LABEL: @test62(
-; CHECK-NEXT: ret i1 true
+; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, i8* [[A:%.*]], i32 1
+; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, i8* [[A]], i32 10
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8* [[ARRAYIDX1]], [[ARRAYIDX2]]
+; CHECK-NEXT: ret i1 [[CMP]]
;
%arrayidx1 = getelementptr inbounds i8, i8* %a, i64 1
%arrayidx2 = getelementptr inbounds i8, i8* %a, i64 10
define i1 @test62_as1(i8 addrspace(1)* %a) {
; CHECK-LABEL: @test62_as1(
-; CHECK-NEXT: ret i1 true
+; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, i8 addrspace(1)* [[A:%.*]], i16 1
+; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, i8 addrspace(1)* [[A]], i16 10
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 addrspace(1)* [[ARRAYIDX1]], [[ARRAYIDX2]]
+; CHECK-NEXT: ret i1 [[CMP]]
;
%arrayidx1 = getelementptr inbounds i8, i8 addrspace(1)* %a, i64 1
%arrayidx2 = getelementptr inbounds i8, i8 addrspace(1)* %a, i64 10
}
declare i32 @test58_d(i64)
+; Negative test: GEP inbounds may cross sign boundary.
define i1 @test62(i8* %a) {
; CHECK-LABEL: @test62(
-; CHECK-NEXT: ret i1 true
+; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, i8* [[A:%.*]], i64 1
+; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 10
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8* [[ARRAYIDX1]], [[ARRAYIDX2]]
+; CHECK-NEXT: ret i1 [[CMP]]
;
%arrayidx1 = getelementptr inbounds i8, i8* %a, i64 1
%arrayidx2 = getelementptr inbounds i8, i8* %a, i64 10
define i1 @test62_as1(i8 addrspace(1)* %a) {
; CHECK-LABEL: @test62_as1(
-; CHECK-NEXT: ret i1 true
+; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, i8 addrspace(1)* [[A:%.*]], i16 1
+; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, i8 addrspace(1)* [[A]], i16 10
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 addrspace(1)* [[ARRAYIDX1]], [[ARRAYIDX2]]
+; CHECK-NEXT: ret i1 [[CMP]]
;
%arrayidx1 = getelementptr inbounds i8, i8 addrspace(1)* %a, i64 1
%arrayidx2 = getelementptr inbounds i8, i8 addrspace(1)* %a, i64 10
define i1 @gep7(%gept* %x) {
; CHECK-LABEL: @gep7(
; CHECK-NEXT: [[A:%.*]] = getelementptr [[GEPT:%.*]], %gept* [[X:%.*]], i64 0, i32 0
-; CHECK-NEXT: [[EQUAL:%.*]] = icmp eq i32* [[A]], getelementptr (%gept, %gept* @gepz, i32 0, i32 0)
+; CHECK-NEXT: [[EQUAL:%.*]] = icmp eq i32* [[A]], getelementptr ([[GEPT]], %gept* @gepz, i32 0, i32 0)
; CHECK-NEXT: ret i1 [[EQUAL]]
;
%a = getelementptr %gept, %gept* %x, i64 0, i32 0
ret i1 %cmp
}
+; Negative test: GEP inbounds may cross sign boundary.
define i1 @gep_same_base_constant_indices(i8* %a) {
; CHECK-LABEL: @gep_same_base_constant_indices(
-; CHECK-NEXT: ret i1 true
+; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, i8* [[A:%.*]], i64 1
+; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 10
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8* [[ARRAYIDX1]], [[ARRAYIDX2]]
+; CHECK-NEXT: ret i1 [[CMP]]
;
%arrayidx1 = getelementptr inbounds i8, i8* %a, i64 1
%arrayidx2 = getelementptr inbounds i8, i8* %a, i64 10