[llvm] r251048 - [SCEV] Mark AddExprs as nsw or nuw if legal
Sanjoy Das via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 22 12:57:20 PDT 2015
Author: sanjoy
Date: Thu Oct 22 14:57:19 2015
New Revision: 251048
URL: http://llvm.org/viewvc/llvm-project?rev=251048&view=rev
Log:
[SCEV] Mark AddExprs as nsw or nuw if legal
Summary:
This uses `ScalarEvolution::getRange` and not potentially control
dependent `nsw` and `nuw` bits on the arithmetic instruction.
Reviewers: atrick, hfinkel, nlewycky
Subscribers: llvm-commits, sanjoy
Differential Revision: http://reviews.llvm.org/D13613
Added:
llvm/trunk/test/Analysis/ScalarEvolution/no-wrap-add-exprs.ll
Modified:
llvm/trunk/lib/Analysis/ScalarEvolution.cpp
llvm/trunk/test/Analysis/Delinearization/multidim_ivs_and_integer_offsets_3d.ll
llvm/trunk/test/Analysis/Delinearization/multidim_ivs_and_integer_offsets_nts_3d.ll
llvm/trunk/test/Analysis/ScalarEvolution/infer-prestart-no-wrap.ll
llvm/trunk/test/Analysis/ScalarEvolution/min-max-exprs.ll
llvm/trunk/test/Transforms/LoopStrengthReduce/quadradic-exit-value.ll
Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=251048&r1=251047&r2=251048&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Thu Oct 22 14:57:19 2015
@@ -1921,8 +1921,9 @@ namespace {
static SCEV::NoWrapFlags
StrengthenNoWrapFlags(ScalarEvolution *SE, SCEVTypes Type,
const SmallVectorImpl<const SCEV *> &Ops,
- SCEV::NoWrapFlags OldFlags) {
+ SCEV::NoWrapFlags Flags) {
using namespace std::placeholders;
+ typedef OverflowingBinaryOperator OBO;
bool CanAnalyze =
Type == scAddExpr || Type == scAddRecExpr || Type == scMulExpr;
@@ -1931,7 +1932,7 @@ StrengthenNoWrapFlags(ScalarEvolution *S
int SignOrUnsignMask = SCEV::FlagNUW | SCEV::FlagNSW;
SCEV::NoWrapFlags SignOrUnsignWrap =
- ScalarEvolution::maskFlags(OldFlags, SignOrUnsignMask);
+ ScalarEvolution::maskFlags(Flags, SignOrUnsignMask);
// If FlagNSW is true and all the operands are non-negative, infer FlagNUW.
auto IsKnownNonNegative =
@@ -1939,10 +1940,34 @@ StrengthenNoWrapFlags(ScalarEvolution *S
if (SignOrUnsignWrap == SCEV::FlagNSW &&
std::all_of(Ops.begin(), Ops.end(), IsKnownNonNegative))
- return ScalarEvolution::setFlags(OldFlags,
- (SCEV::NoWrapFlags)SignOrUnsignMask);
+ Flags =
+ ScalarEvolution::setFlags(Flags, (SCEV::NoWrapFlags)SignOrUnsignMask);
- return OldFlags;
+ SignOrUnsignWrap = ScalarEvolution::maskFlags(Flags, SignOrUnsignMask);
+
+ if (SignOrUnsignWrap != SignOrUnsignMask && Type == scAddExpr &&
+ Ops.size() == 2 && isa<SCEVConstant>(Ops[0])) {
+
+ // (A + C) --> (A + C)<nsw> if the addition does not sign overflow
+ // (A + C) --> (A + C)<nuw> if the addition does not unsign overflow
+
+ const APInt &C = cast<SCEVConstant>(Ops[0])->getValue()->getValue();
+ if (!(SignOrUnsignWrap & SCEV::FlagNSW)) {
+ auto NSWRegion =
+ ConstantRange::makeNoWrapRegion(Instruction::Add, C, OBO::NoSignedWrap);
+ if (NSWRegion.contains(SE->getSignedRange(Ops[1])))
+ Flags = ScalarEvolution::setFlags(Flags, SCEV::FlagNSW);
+ }
+ if (!(SignOrUnsignWrap & SCEV::FlagNUW)) {
+ auto NUWRegion =
+ ConstantRange::makeNoWrapRegion(Instruction::Add, C,
+ OBO::NoUnsignedWrap);
+ if (NUWRegion.contains(SE->getUnsignedRange(Ops[1])))
+ Flags = ScalarEvolution::setFlags(Flags, SCEV::FlagNUW);
+ }
+ }
+
+ return Flags;
}
/// getAddExpr - Get a canonical add expression, or something simpler if
Modified: llvm/trunk/test/Analysis/Delinearization/multidim_ivs_and_integer_offsets_3d.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/Delinearization/multidim_ivs_and_integer_offsets_3d.ll?rev=251048&r1=251047&r2=251048&view=diff
==============================================================================
--- llvm/trunk/test/Analysis/Delinearization/multidim_ivs_and_integer_offsets_3d.ll (original)
+++ llvm/trunk/test/Analysis/Delinearization/multidim_ivs_and_integer_offsets_3d.ll Thu Oct 22 14:57:19 2015
@@ -11,7 +11,7 @@
; AddRec: {{{(56 + (8 * (-4 + (3 * %m)) * %o) + %A),+,(8 * %m * %o)}<%for.i>,+,(8 * %o)}<%for.j>,+,8}<%for.k>
; CHECK: Base offset: %A
; CHECK: ArrayDecl[UnknownSize][%m][%o] with elements of 8 bytes.
-; CHECK: ArrayRef[{3,+,1}<nw><%for.i>][{-4,+,1}<nw><%for.j>][{7,+,1}<nuw><nsw><%for.k>]
+; CHECK: ArrayRef[{3,+,1}<nuw><%for.i>][{-4,+,1}<nw><%for.j>][{7,+,1}<nuw><nsw><%for.k>]
define void @foo(i64 %n, i64 %m, i64 %o, double* %A) {
entry:
Modified: llvm/trunk/test/Analysis/Delinearization/multidim_ivs_and_integer_offsets_nts_3d.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/Delinearization/multidim_ivs_and_integer_offsets_nts_3d.ll?rev=251048&r1=251047&r2=251048&view=diff
==============================================================================
--- llvm/trunk/test/Analysis/Delinearization/multidim_ivs_and_integer_offsets_nts_3d.ll (original)
+++ llvm/trunk/test/Analysis/Delinearization/multidim_ivs_and_integer_offsets_nts_3d.ll Thu Oct 22 14:57:19 2015
@@ -11,7 +11,7 @@
; AddRec: {{{(56 + (8 * (-4 + (3 * %m)) * (%o + %p)) + %A),+,(8 * (%o + %p) * %m)}<%for.cond4.preheader.lr.ph.us>,+,(8 * (%o + %p))}<%for.body6.lr.ph.us.us>,+,8}<%for.body6.us.us>
; CHECK: Base offset: %A
; CHECK: ArrayDecl[UnknownSize][%m][(%o + %p)] with elements of 8 bytes.
-; CHECK: ArrayRef[{3,+,1}<nw><%for.cond4.preheader.lr.ph.us>][{-4,+,1}<nw><%for.body6.lr.ph.us.us>][{7,+,1}<nw><%for.body6.us.us>]
+; CHECK: ArrayRef[{3,+,1}<nuw><%for.cond4.preheader.lr.ph.us>][{-4,+,1}<nw><%for.body6.lr.ph.us.us>][{7,+,1}<nw><%for.body6.us.us>]
define void @foo(i64 %n, i64 %m, i64 %o, i64 %p, double* nocapture %A) nounwind uwtable {
entry:
Modified: llvm/trunk/test/Analysis/ScalarEvolution/infer-prestart-no-wrap.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/infer-prestart-no-wrap.ll?rev=251048&r1=251047&r2=251048&view=diff
==============================================================================
--- llvm/trunk/test/Analysis/ScalarEvolution/infer-prestart-no-wrap.ll (original)
+++ llvm/trunk/test/Analysis/ScalarEvolution/infer-prestart-no-wrap.ll Thu Oct 22 14:57:19 2015
@@ -11,7 +11,7 @@ define void @infer.sext.0(i1* %c, i32 %s
%idx.inc = add nsw i32 %idx, 1
%idx.inc.sext = sext i32 %idx.inc to i64
; CHECK: %idx.inc.sext = sext i32 %idx.inc to i64
-; CHECK-NEXT: --> {(1 + (sext i32 %start to i64)),+,1}<nsw><%loop>
+; CHECK-NEXT: --> {(1 + (sext i32 %start to i64))<nsw>,+,1}<nsw><%loop>
%condition = icmp eq i32 %counter, 1
%counter.inc = add i32 %counter, 1
br i1 %condition, label %exit, label %loop
@@ -31,7 +31,7 @@ define void @infer.zext.0(i1* %c, i32 %s
%idx.inc = add nuw i32 %idx, 1
%idx.inc.sext = zext i32 %idx.inc to i64
; CHECK: %idx.inc.sext = zext i32 %idx.inc to i64
-; CHECK-NEXT: --> {(1 + (zext i32 %start to i64)),+,1}<nuw><%loop>
+; CHECK-NEXT: --> {(1 + (zext i32 %start to i64))<nuw><nsw>,+,1}<nuw><%loop>
%condition = icmp eq i32 %counter, 1
%counter.inc = add i32 %counter, 1
br i1 %condition, label %exit, label %loop
@@ -51,7 +51,7 @@ define void @infer.sext.1(i32 %start, i1
%idx = phi i32 [ %start.real, %entry ], [ %idx.inc, %loop ]
%idx.sext = sext i32 %idx to i64
; CHECK: %idx.sext = sext i32 %idx to i64
-; CHECK-NEXT: --> {(2 + (sext i32 (4 * %start) to i64)),+,2}<nsw><%loop>
+; CHECK-NEXT: --> {(2 + (sext i32 (4 * %start) to i64))<nsw>,+,2}<nsw><%loop>
%idx.inc = add nsw i32 %idx, 2
%condition = load i1, i1* %c
br i1 %condition, label %exit, label %loop
@@ -71,7 +71,7 @@ define void @infer.sext.2(i1* %c, i8 %st
%idx = phi i8 [ %start.inc, %entry ], [ %idx.inc, %loop ]
%idx.sext = sext i8 %idx to i16
; CHECK: %idx.sext = sext i8 %idx to i16
-; CHECK-NEXT: --> {(1 + (sext i8 %start to i16)),+,1}<nsw><%loop>
+; CHECK-NEXT: --> {(1 + (sext i8 %start to i16))<nsw>,+,1}<nsw><%loop>
%idx.inc = add nsw i8 %idx, 1
%condition = load volatile i1, i1* %c
br i1 %condition, label %exit, label %loop
@@ -91,7 +91,7 @@ define void @infer.zext.1(i1* %c, i8 %st
%idx = phi i8 [ %start.inc, %entry ], [ %idx.inc, %loop ]
%idx.zext = zext i8 %idx to i16
; CHECK: %idx.zext = zext i8 %idx to i16
-; CHECK-NEXT: --> {(1 + (zext i8 %start to i16)),+,1}<nuw><%loop>
+; CHECK-NEXT: --> {(1 + (zext i8 %start to i16))<nuw><nsw>,+,1}<nuw><%loop>
%idx.inc = add nuw i8 %idx, 1
%condition = load volatile i1, i1* %c
br i1 %condition, label %exit, label %loop
Modified: llvm/trunk/test/Analysis/ScalarEvolution/min-max-exprs.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/min-max-exprs.ll?rev=251048&r1=251047&r2=251048&view=diff
==============================================================================
--- llvm/trunk/test/Analysis/ScalarEvolution/min-max-exprs.ll (original)
+++ llvm/trunk/test/Analysis/ScalarEvolution/min-max-exprs.ll Thu Oct 22 14:57:19 2015
@@ -33,7 +33,7 @@ bb2:
%tmp9 = select i1 %tmp4, i64 %tmp5, i64 %tmp6
; min(N, i+3)
; CHECK: select i1 %tmp4, i64 %tmp5, i64 %tmp6
-; CHECK-NEXT: --> (-1 + (-1 * ((-1 + (-1 * (sext i32 {3,+,1}<nw><%bb1> to i64))<nsw>) smax (-1 + (-1 * (sext i32 %N to i64))<nsw>)))<nsw>)
+; CHECK-NEXT: --> (-1 + (-1 * ((-1 + (-1 * (sext i32 {3,+,1}<nuw><%bb1> to i64))<nsw>)<nsw> smax (-1 + (-1 * (sext i32 %N to i64))<nsw>)<nsw>))<nsw>)<nsw>
%tmp11 = getelementptr inbounds i32, i32* %A, i64 %tmp9
%tmp12 = load i32, i32* %tmp11, align 4
%tmp13 = shl nsw i32 %tmp12, 1
Added: llvm/trunk/test/Analysis/ScalarEvolution/no-wrap-add-exprs.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/no-wrap-add-exprs.ll?rev=251048&view=auto
==============================================================================
--- llvm/trunk/test/Analysis/ScalarEvolution/no-wrap-add-exprs.ll (added)
+++ llvm/trunk/test/Analysis/ScalarEvolution/no-wrap-add-exprs.ll Thu Oct 22 14:57:19 2015
@@ -0,0 +1,44 @@
+; RUN: opt -S -analyze -scalar-evolution < %s | FileCheck %s
+
+!0 = !{i8 0, i8 127}
+
+define void @f0(i8* %len_addr) {
+; CHECK-LABEL: Classifying expressions for: @f0
+ entry:
+ %len = load i8, i8* %len_addr, !range !0
+ %len_norange = load i8, i8* %len_addr
+; CHECK: %len = load i8, i8* %len_addr, !range !0
+; CHECK-NEXT: --> %len U: [0,127) S: [0,127)
+; CHECK: %len_norange = load i8, i8* %len_addr
+; CHECK-NEXT: --> %len_norange U: full-set S: full-set
+
+ %t0 = add i8 %len, 1
+ %t1 = add i8 %len, 2
+; CHECK: %t0 = add i8 %len, 1
+; CHECK-NEXT: --> (1 + %len)<nuw><nsw> U: [1,-128) S: [1,-128)
+; CHECK: %t1 = add i8 %len, 2
+; CHECK-NEXT: --> (2 + %len)<nuw> U: [2,-127) S: [2,-127)
+
+ %t2 = sub i8 %len, 1
+ %t3 = sub i8 %len, 2
+; CHECK: %t2 = sub i8 %len, 1
+; CHECK-NEXT: --> (-1 + %len)<nsw> U: [-1,126) S: [-1,126)
+; CHECK: %t3 = sub i8 %len, 2
+; CHECK-NEXT: --> (-2 + %len)<nsw> U: [-2,125) S: [-2,125)
+
+ %q0 = add i8 %len_norange, 1
+ %q1 = add i8 %len_norange, 2
+; CHECK: %q0 = add i8 %len_norange, 1
+; CHECK-NEXT: --> (1 + %len_norange) U: full-set S: full-set
+; CHECK: %q1 = add i8 %len_norange, 2
+; CHECK-NEXT: --> (2 + %len_norange) U: full-set S: full-set
+
+ %q2 = sub i8 %len_norange, 1
+ %q3 = sub i8 %len_norange, 2
+; CHECK: %q2 = sub i8 %len_norange, 1
+; CHECK-NEXT: --> (-1 + %len_norange) U: full-set S: full-set
+; CHECK: %q3 = sub i8 %len_norange, 2
+; CHECK-NEXT: --> (-2 + %len_norange) U: full-set S: full-set
+
+ ret void
+}
Modified: llvm/trunk/test/Transforms/LoopStrengthReduce/quadradic-exit-value.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopStrengthReduce/quadradic-exit-value.ll?rev=251048&r1=251047&r2=251048&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/LoopStrengthReduce/quadradic-exit-value.ll (original)
+++ llvm/trunk/test/Transforms/LoopStrengthReduce/quadradic-exit-value.ll Thu Oct 22 14:57:19 2015
@@ -28,7 +28,7 @@ exit:
; sure they aren't marked as post-inc users.
;
; CHECK-LABEL: IV Users for loop %test2.loop
-; CHECK: %sext.us = {0,+,(16777216 + (-16777216 * %sub.us)),+,33554432}<%test2.loop> in %f = ashr i32 %sext.us, 24
+; CHECK: %sext.us = {0,+,(16777216 + (-16777216 * %sub.us))<nuw><nsw>,+,33554432}<%test2.loop> in %f = ashr i32 %sext.us, 24
define i32 @test2() {
entry:
br label %test2.loop
More information about the llvm-commits
mailing list