diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -6302,6 +6302,24 @@ return getSCEV(U->getOperand(0)); break; + case Instruction::IntToPtr: + case Instruction::PtrToInt: + // It's tempting to handle inttoptr and ptrtoint as no-ops, + // however this can lead to pointer expressions which cannot safely be + // expanded to GEPs because ScalarEvolution doesn't respect + // the GEP aliasing rules when simplifying integer expressions. + // + // However, given + // %x = ??? + // %y = inttoptr %x or %y = ptrtoint %x + // %z = inttoptr %x or %z = ptrtoint %x + // it is safe to say that %y and %z are the same thing. + // + // So instead of modelling the cast itself as unknown, + // since the casts are transparent within SCEV, + // we can at least model the casts original value as unknow instead. + return getTruncateOrZeroExtend(getUnknown(U->getOperand(0)), U->getType()); + case Instruction::SDiv: // If both operands are non-negative, this is just an udiv. if (isKnownNonNegative(getSCEV(U->getOperand(0))) && @@ -6316,11 +6334,6 @@ return getURemExpr(getSCEV(U->getOperand(0)), getSCEV(U->getOperand(1))); break; - // It's tempting to handle inttoptr and ptrtoint as no-ops, however this can - // lead to pointer expressions which cannot safely be expanded to GEPs, - // because ScalarEvolution doesn't respect the GEP aliasing rules when - // simplifying integer expressions. - case Instruction::GetElementPtr: return createNodeForGEP(cast(U)); diff --git a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp --- a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp @@ -427,7 +427,7 @@ : &ScalarEvolution::getZeroExtendExpr; // Check ext(LHS op RHS) == ext(LHS) op ext(RHS) - auto *NarrowTy = cast(LHS->getType()); + auto *NarrowTy = cast(SE->getEffectiveSCEVType(LHS->getType())); auto *WideTy = IntegerType::get(NarrowTy->getContext(), NarrowTy->getBitWidth() * 2); diff --git a/llvm/test/Analysis/ScalarEvolution/add-expr-pointer-operand-sorting.ll b/llvm/test/Analysis/ScalarEvolution/add-expr-pointer-operand-sorting.ll --- a/llvm/test/Analysis/ScalarEvolution/add-expr-pointer-operand-sorting.ll +++ b/llvm/test/Analysis/ScalarEvolution/add-expr-pointer-operand-sorting.ll @@ -33,9 +33,9 @@ ; CHECK-NEXT: %1 = load i32*, i32** @c, align 8 ; CHECK-NEXT: --> %1 U: full-set S: full-set Exits: <> LoopDispositions: { %for.cond: Variant } ; CHECK-NEXT: %sub.ptr.lhs.cast = ptrtoint i32* %1 to i64 -; CHECK-NEXT: --> %sub.ptr.lhs.cast U: full-set S: full-set Exits: <> LoopDispositions: { %for.cond: Variant } +; CHECK-NEXT: --> %1 U: full-set S: full-set Exits: <> LoopDispositions: { %for.cond: Variant } ; CHECK-NEXT: %sub.ptr.sub = sub i64 %sub.ptr.lhs.cast, ptrtoint ([1 x i32]* @b to i64) -; CHECK-NEXT: --> ((-1 * ptrtoint ([1 x i32]* @b to i64)) + %sub.ptr.lhs.cast) U: full-set S: full-set Exits: <> LoopDispositions: { %for.cond: Variant } +; CHECK-NEXT: --> ((-1 * @b) + %1) U: full-set S: full-set Exits: <> LoopDispositions: { %for.cond: Variant } ; CHECK-NEXT: %sub.ptr.div = sdiv exact i64 %sub.ptr.sub, 4 ; CHECK-NEXT: --> %sub.ptr.div U: full-set S: [-2305843009213693952,2305843009213693952) Exits: <> LoopDispositions: { %for.cond: Variant } ; CHECK-NEXT: %arrayidx1 = getelementptr inbounds [1 x i8], [1 x i8]* %arrayidx, i64 0, i64 %sub.ptr.div diff --git a/llvm/test/Analysis/ScalarEvolution/no-wrap-add-exprs.ll b/llvm/test/Analysis/ScalarEvolution/no-wrap-add-exprs.ll --- a/llvm/test/Analysis/ScalarEvolution/no-wrap-add-exprs.ll +++ b/llvm/test/Analysis/ScalarEvolution/no-wrap-add-exprs.ll @@ -170,14 +170,14 @@ %int5 = add i32 %int0, 5 %int.zext = zext i32 %int5 to i64 ; CHECK: %int.zext = zext i32 %int5 to i64 -; CHECK-NEXT: --> (1 + (zext i32 (4 + %int0) to i64)) U: [1,4294967294) S: [1,4294967297) +; CHECK-NEXT: --> (1 + (zext i32 (4 + (trunc i8* %ptr to i32)) to i64)) U: [1,4294967294) S: [1,4294967297) %ptr_noalign = bitcast [16 x i8]* @z_addr_noalign to i8* %int0_na = ptrtoint i8* %ptr_noalign to i32 %int5_na = add i32 %int0_na, 5 %int.zext_na = zext i32 %int5_na to i64 ; CHECK: %int.zext_na = zext i32 %int5_na to i64 -; CHECK-NEXT: --> (zext i32 (5 + %int0_na) to i64) U: [0,4294967296) S: [0,4294967296) +; CHECK-NEXT: --> (zext i32 (5 + (trunc i8* %ptr_noalign to i32)) to i64) U: [0,4294967296) S: [0,4294967296) %tmp = load i32, i32* %tmp_addr %mul = and i32 %tmp, -4 diff --git a/llvm/test/Analysis/ScalarEvolution/scalable-vector.ll b/llvm/test/Analysis/ScalarEvolution/scalable-vector.ll --- a/llvm/test/Analysis/ScalarEvolution/scalable-vector.ll +++ b/llvm/test/Analysis/ScalarEvolution/scalable-vector.ll @@ -2,9 +2,9 @@ ; RUN: opt "-passes=print" -disable-output < %s 2>&1 | FileCheck %s ; CHECK: %1 = getelementptr , * null, i32 3 -; CHECK: --> (3 * sizeof()) U: [0,-15) S: [-9223372036854775808,9223372036854775793) +; CHECK: --> (3 * getelementptr (, * null, i64 1)) U: [0,-15) S: [-9223372036854775808,9223372036854775793) ; CHECK: %2 = getelementptr , * %p, i32 1 -; CHECK: --> (sizeof() + %p) U: full-set S: full-set +; CHECK: --> (getelementptr (, * null, i64 1) + %p) U: full-set S: full-set define void @a( *%p) { getelementptr , *null, i32 3 getelementptr , *%p, i32 1 diff --git a/llvm/test/Analysis/ScalarEvolution/semi-transparent-inttoptr-ptrtoint-casts.ll b/llvm/test/Analysis/ScalarEvolution/semi-transparent-inttoptr-ptrtoint-casts.ll --- a/llvm/test/Analysis/ScalarEvolution/semi-transparent-inttoptr-ptrtoint-casts.ll +++ b/llvm/test/Analysis/ScalarEvolution/semi-transparent-inttoptr-ptrtoint-casts.ll @@ -19,13 +19,13 @@ ; CHECK-NEXT: %in_adj = getelementptr inbounds i8, i8* %in, i64 42 ; CHECK-NEXT: --> (42 + %in) U: [-9223372036854775766,-9223372036854775808) S: [-9223372036854775766,-9223372036854775808) ; CHECK-NEXT: %p0 = ptrtoint i8* %in_adj to i64 -; CHECK-NEXT: --> %p0 U: full-set S: full-set +; CHECK-NEXT: --> %in_adj U: full-set S: full-set ; CHECK-NEXT: %p1 = ptrtoint i8* %in_adj to i64 -; CHECK-NEXT: --> %p1 U: full-set S: full-set +; CHECK-NEXT: --> %in_adj U: full-set S: full-set ; CHECK-NEXT: %p2 = ptrtoint i8* %in_adj to i32 -; CHECK-NEXT: --> %p2 U: full-set S: full-set +; CHECK-NEXT: --> (trunc i8* %in_adj to i32) U: full-set S: full-set ; CHECK-NEXT: %p3 = ptrtoint i8* %in_adj to i128 -; CHECK-NEXT: --> %p3 U: [0,18446744073709551616) S: [-18446744073709551616,18446744073709551616) +; CHECK-NEXT: --> (zext i8* %in_adj to i128) U: [0,18446744073709551616) S: [0,18446744073709551616) ; CHECK-NEXT: Determining loop execution counts for: @ptrtoint ; %in_adj = getelementptr inbounds i8, i8* %in, i64 42 @@ -46,9 +46,9 @@ ; CHECK-NEXT: %in_adj = add i64 %in0, 42 ; CHECK-NEXT: --> (42 + %in0) U: full-set S: full-set ; CHECK-NEXT: %i0 = inttoptr i64 %in_adj to i8* -; CHECK-NEXT: --> %i0 U: full-set S: full-set +; CHECK-NEXT: --> %in_adj U: full-set S: full-set ; CHECK-NEXT: %i1 = inttoptr i64 %in_adj to i8* -; CHECK-NEXT: --> %i1 U: full-set S: full-set +; CHECK-NEXT: --> %in_adj U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @inttoptr ; %in_adj = add i64 %in0, 42 @@ -64,7 +64,7 @@ ; CHECK-NEXT: %in_adj = add i32 %in1, 42 ; CHECK-NEXT: --> (42 + %in1) U: full-set S: full-set ; CHECK-NEXT: %i0 = inttoptr i32 %in_adj to i8* -; CHECK-NEXT: --> %i0 U: [0,4294967296) S: [-4294967296,4294967296) +; CHECK-NEXT: --> (zext i32 %in_adj to i64) U: [0,4294967296) S: [0,4294967296) ; CHECK-NEXT: Determining loop execution counts for: @inttoptr_widening ; %in_adj = add i32 %in1, 42 @@ -78,7 +78,7 @@ ; CHECK-NEXT: %in_adj = add i128 %in2, 42 ; CHECK-NEXT: --> (42 + %in2) U: full-set S: full-set ; CHECK-NEXT: %i0 = inttoptr i128 %in_adj to i8* -; CHECK-NEXT: --> %i0 U: full-set S: full-set +; CHECK-NEXT: --> (trunc i128 %in_adj to i64) U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @inttoptr_narrowing ; %in_adj = add i128 %in2, 42 @@ -92,17 +92,17 @@ ; CHECK-LABEL: 'onlysemitransparency' ; CHECK-NEXT: Classifying expressions for: @onlysemitransparency ; CHECK-NEXT: %i0 = ptrtoint i8* %in to i64 -; CHECK-NEXT: --> %i0 U: full-set S: full-set +; CHECK-NEXT: --> %in U: full-set S: full-set ; CHECK-NEXT: %i1 = inttoptr i64 %i0 to i8* -; CHECK-NEXT: --> %i1 U: full-set S: full-set +; CHECK-NEXT: --> %i0 U: full-set S: full-set ; CHECK-NEXT: %i2 = ptrtoint i8* %i1 to i64 -; CHECK-NEXT: --> %i2 U: full-set S: full-set +; CHECK-NEXT: --> %i1 U: full-set S: full-set ; CHECK-NEXT: %i3 = inttoptr i64 %i2 to i8* -; CHECK-NEXT: --> %i3 U: full-set S: full-set +; CHECK-NEXT: --> %i2 U: full-set S: full-set ; CHECK-NEXT: %i4 = ptrtoint i8* %i3 to i64 -; CHECK-NEXT: --> %i4 U: full-set S: full-set +; CHECK-NEXT: --> %i3 U: full-set S: full-set ; CHECK-NEXT: %i5 = inttoptr i64 %i4 to i8* -; CHECK-NEXT: --> %i5 U: full-set S: full-set +; CHECK-NEXT: --> %i4 U: full-set S: full-set ; CHECK-NEXT: Determining loop execution counts for: @onlysemitransparency ; %i0 = ptrtoint i8* %in to i64 diff --git a/llvm/test/CodeGen/ARM/lsr-undef-in-binop.ll b/llvm/test/CodeGen/ARM/lsr-undef-in-binop.ll --- a/llvm/test/CodeGen/ARM/lsr-undef-in-binop.ll +++ b/llvm/test/CodeGen/ARM/lsr-undef-in-binop.ll @@ -186,7 +186,8 @@ br i1 %114, label %124, label %115 ; CHECK-LABEL: .preheader: -; CHECK-NEXT: sub i32 [[OLD_CAST]], [[NEW_CAST]] +; CHECK-NEXT: [[NEG_NEW_CAST:%[0-9]+]] = sub i32 0, [[NEW_CAST]] +; CHECK-NEXT: getelementptr i8, i8* %97, i32 [[NEG_NEW_CAST]] ;