Avoid creating canonical induction variables for non-native types.
authorAndrew Trick <atrick@apple.com>
Fri, 18 Mar 2011 16:50:32 +0000 (16:50 +0000)
committerAndrew Trick <atrick@apple.com>
Fri, 18 Mar 2011 16:50:32 +0000 (16:50 +0000)
For example, on 32-bit architecture, don't promote all uses of the IV
to 64-bits just because one use is a 64-bit cast.
Alternate implementation of the patch by Arnaud de Grandmaison.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127884 91177308-0d34-0410-b5e6-96231b3b80d8

20 files changed:
include/llvm/Analysis/IVUsers.h
lib/Analysis/IVUsers.cpp
test/Transforms/IndVarSimplify/2009-04-14-shorten_iv_vars.ll
test/Transforms/IndVarSimplify/2009-04-15-shorten-iv-vars-2.ll
test/Transforms/IndVarSimplify/ada-loops.ll
test/Transforms/IndVarSimplify/addrec-gep.ll
test/Transforms/IndVarSimplify/ashr-tripcount.ll
test/Transforms/IndVarSimplify/iv-sext.ll
test/Transforms/IndVarSimplify/iv-zext.ll
test/Transforms/IndVarSimplify/max-pointer.ll
test/Transforms/IndVarSimplify/pointer.ll
test/Transforms/IndVarSimplify/preserve-gep-loop-variant.ll
test/Transforms/IndVarSimplify/preserve-gep-nested.ll
test/Transforms/IndVarSimplify/preserve-gep-remainder.ll
test/Transforms/IndVarSimplify/preserve-gep.ll
test/Transforms/LoopSimplify/merge-exits.ll
test/Transforms/LoopStrengthReduce/invariant_value_first.ll
test/Transforms/LoopStrengthReduce/invariant_value_first_arg.ll
test/Transforms/LoopStrengthReduce/ops_after_indvar.ll
test/Transforms/LoopStrengthReduce/var_stride_used_by_compare.ll

index 578e6aba8338521203b1ec760193012680c32c98..e56d24d583dfad6ef44859f77ef174e80a29b832 100644 (file)
@@ -28,6 +28,7 @@ class IVUsers;
 class ScalarEvolution;
 class SCEV;
 class IVUsers;
+class TargetData;
 
 /// IVStrideUse - Keep track of one use of a strided induction variable.
 /// The Expr member keeps track of the expression, User is the actual user
@@ -122,6 +123,7 @@ class IVUsers : public LoopPass {
   LoopInfo *LI;
   DominatorTree *DT;
   ScalarEvolution *SE;
+  TargetData *TD;
   SmallPtrSet<Instruction*,16> Processed;
 
   /// IVUses - A list of all tracked IV uses of induction variable expressions
index c8382186df3afe8fb365c0b55d50293b22d70827..2cda7913f024842e01a1f18d2363e24413716f90 100644 (file)
@@ -21,6 +21,7 @@
 #include "llvm/Analysis/Dominators.h"
 #include "llvm/Analysis/LoopPass.h"
 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
+#include "llvm/Target/TargetData.h"
 #include "llvm/Assembly/Writer.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/Debug.h"
@@ -83,7 +84,10 @@ bool IVUsers::AddUsersIfInteresting(Instruction *I) {
     return false;   // Void and FP expressions cannot be reduced.
 
   // LSR is not APInt clean, do not touch integers bigger than 64-bits.
-  if (SE->getTypeSizeInBits(I->getType()) > 64)
+  // Also avoid creating IVs of non-native types. For example, we don't want a
+  // 64-bit IV in 32-bit code just because the loop has one 64-bit cast.
+  uint64_t Width = SE->getTypeSizeInBits(I->getType());
+  if (Width > 64 || (TD && !TD->isLegalInteger(Width)))
     return false;
 
   if (!Processed.insert(I))
@@ -167,6 +171,7 @@ bool IVUsers::runOnLoop(Loop *l, LPPassManager &LPM) {
   LI = &getAnalysis<LoopInfo>();
   DT = &getAnalysis<DominatorTree>();
   SE = &getAnalysis<ScalarEvolution>();
+  TD = getAnalysisIfAvailable<TargetData>();
 
   // Find all uses of induction variables in this loop, and categorize
   // them by stride.  Start by finding all of the PHI nodes in the header for
index 37ad63a9a77298f5d2f1d5f9a222525ca8876423..0f6267bd17991618259c4b385c7fd1fea35f0741 100644 (file)
@@ -1,6 +1,6 @@
 ; RUN: opt < %s -indvars -S | not grep {sext}
 ; ModuleID = '<stdin>'
-target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n:32:64"
 target triple = "x86_64-apple-darwin9.6"
 @a = external global i32*              ; <i32**> [#uses=3]
 @b = external global i32*              ; <i32**> [#uses=3]
index 803b540606e5cfb5f75f4d619de050327d7433fa..46d6b380f0000fc9a7e37328f6053c5fc561b6a3 100644 (file)
@@ -13,7 +13,7 @@
 ;    d[(i+2)&15] = e[(i+2)&15]+f[(i+2)&15]+K[i+2];
 ;  }
 ;}
-target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n:32:64"
 target triple = "x86_64-apple-darwin9.6"
 @a = external global i32*              ; <i32**> [#uses=3]
 @b = external global i32*              ; <i32**> [#uses=3]
index 436840ae907502fe1c37ce25e824f88e808635d0..4a07d997e7d72c29e52771db41dccabb47bdf80f 100644 (file)
@@ -11,7 +11,7 @@
 ; count without casting.
 
 ; ModuleID = 'ada.bc'
-target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64"
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-n:8:16:32"
 target triple = "i686-pc-linux-gnu"
 
 define void @kinds__sbytezero([256 x i32]* nocapture %a) nounwind {
index 345f666c3b2ea64465d3d2dedf52e871caffbd2a..58cba6057045de19c1c97bb33b7556c517a25d98 100644 (file)
@@ -9,7 +9,7 @@
 ; be able to reconstruct the full getelementptr, despite it having a few
 ; obstacles set in its way.
 
-target datalayout = "e-p:64:64:64"
+target datalayout = "e-p:64:64:64-n:32:64"
 
 define void @foo(i64 %n, i64 %m, i64 %o, i64 %q, double* nocapture %p) nounwind {
 entry:
index baaefdc2bc51dd19784b7b3d4b5e35b83aca77f2..09d559fe511497e8de50c02dd9aaa0ff1aae1a51 100644 (file)
@@ -4,7 +4,7 @@
 ; Indvars should be able to eliminate all of the sign extensions
 ; inside the loop.
 
-target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n:32:64"
 @pow_2_tab = external constant [0 x float]             ; <[0 x float]*> [#uses=1]
 @pow_2_025_tab = external constant [0 x float]         ; <[0 x float]*> [#uses=1]
 @i_pow_2_tab = external constant [0 x float]           ; <[0 x float]*> [#uses=1]
index 55165022109a6de7a653ba80eecb8a9ca34ac91f..3e90873992493a03de600c642ce6a69b7862911e 100644 (file)
@@ -6,7 +6,7 @@
 ; inner loop to i64.
 ; TODO: it should promote hiPart to i64 in the outer loop too.
 
-target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n:32:64"
 
 define void @t(float* %pTmp1, float* %peakWeight, float* %nrgReducePeakrate, i32 %bandEdgeIndex, float %tmp1) nounwind {
 entry:
index 1cc559fd79f1b207f1b8b8c2f59e10c97dbab2b0..80a77b6e9365f9eae055960d9a011a1f852b6816 100644 (file)
@@ -2,7 +2,7 @@
 ; RUN: not grep and %t
 ; RUN: not grep zext %t
 
-target datalayout = "-p:64:64:64"
+target datalayout = "-p:64:64:64-n:32:64"
 
 define void @foo(double* %d, i64 %n) nounwind {
 entry:
index f18f968f595d53eb6f1eeb843fc583d25db811b6..46ac2d89b50432377317ba671c61931d1e18fc58 100644 (file)
@@ -2,7 +2,7 @@
 ; RUN: grep {icmp ugt i8\\\*} %t | count 1
 ; RUN: grep {icmp sgt i8\\\*} %t | count 1
 
-target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n:32:64"
 
        %struct.CKenCodeCodec = type <{ i8 }>
 
index 5eee655d4225b29ea7314194c22bb69cd6593eb3..d55bf98d3136278ca8e1ea9ad5b5a2c3655e817d 100644 (file)
@@ -9,7 +9,7 @@
 ; Indvars should be able to expand the pointer-arithmetic
 ; IV into an integer IV indexing into a simple getelementptr.
 
-target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64"
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-n:32:64"
 
 define void @foo(i8* %A, i64 %n) nounwind {
 entry:
index 3a5c0b650ffebfb87738b5d95e0e6af5198d5f94..26f05c4b1ee913ece18d8f5d2323ed940791fccb 100644 (file)
@@ -2,7 +2,7 @@
 ; RUN: not grep inttoptr %t
 ; RUN: not grep ptrtoint %t
 ; RUN: grep scevgep %t
-target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
+target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128-n:32:64"
 
 ; Indvars shouldn't need inttoptr/ptrtoint to expand an address here.
 
index bb0993c88eabd86b8a36e381a0c42c3f7e15f1a8..b41de5828a9ddc10ca5dea7514fd565ffc8d7dc5 100644 (file)
@@ -13,7 +13,7 @@
 
 ; FIXME: This test should pass with or without TargetData. Until opt
 ; supports running tests without targetdata, just hardware this in.
-target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n:32:64"
 
 %struct.Q = type { [10 x %struct.N] }
 %struct.N = type { %struct.S }
index e17368b04ccfa820784c7caf265d690e4c173ddc..ca0c3999276024bee64a769bcfbcb541ab9b192d 100644 (file)
@@ -1,6 +1,6 @@
 ; RUN: opt < %s -indvars -S \
 ; RUN:   | grep {\[%\]p.2.ip.1 = getelementptr \\\[3 x \\\[3 x double\\\]\\\]\\* \[%\]p, i64 2, i64 \[%\]tmp, i64 1}
-target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
+target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128-n:32:64"
 
 ; Indvars shouldn't expand this to
 ;   %p.2.ip.1 = getelementptr [3 x [3 x double]]* %p, i64 0, i64 %tmp, i64 19
index a27d20dc965315f3c57c6a267e6a32e420544c43..82eda0386e7fd0439c0cf853dda811e10b7cea73 100644 (file)
@@ -6,7 +6,7 @@
 ; Indvars shouldn't leave getelementptrs expanded out as
 ; inttoptr+ptrtoint in its output in common cases.
 
-target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n:32:64"
 target triple = "x86_64-unknown-linux-gnu"
        %struct.Foo = type { i32, i32, [10 x i32], i32 }
 
index 93a224744ca3962747695c6a9366e0c3d439b0cd..e5e471766b9a25986b1d1eb1da6daf6b79a1acc4 100644 (file)
@@ -7,7 +7,7 @@
 ; that indvars can promote the induction variable to i64
 ; without needing casts.
 
-target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n:32:64"
 
 define float @t(float* %pTmp1, float* %peakWeight, i32 %bandEdgeIndex) nounwind {
 entry:
index 4094e9c7e4d9f9601cef21af0f268f1347a5cf32..986a55a3f6c4e80b94dd9601e65222d37a8645ee 100644 (file)
@@ -1,7 +1,8 @@
 ; Check that the index of 'P[outer]' is pulled out of the loop.
-; RUN: opt < %s -loop-reduce -S -default-data-layout="e-p:32:32:32" | \
+; RUN: opt < %s -loop-reduce -S | \
 ; RUN:   not grep {getelementptr.*%outer.*%INDVAR}
 
+target datalayout = "e-p:32:32:32-n:8:16:32"
 declare i1 @pred()
 
 declare i32 @foo()
index e2aed78c32e3c10d97071c937961673ea994c3ad..1d43961c356e11bf5d63831e45d7c54e963f6b35 100644 (file)
@@ -1,7 +1,8 @@
 ; Check that the index of 'P[outer]' is pulled out of the loop.
-; RUN: opt < %s -loop-reduce -S -default-data-layout="e-p:32:32:32" | \
+; RUN: opt < %s -loop-reduce -S | \
 ; RUN:   not grep {getelementptr.*%outer.*%INDVAR}
 
+target datalayout = "e-p:32:32:32-n:32"
 declare i1 @pred()
 
 define void @test([10000 x i32]* %P, i32 %outer) {
index 410d88f672b54cb72a833bde55105284ebeaa404..00bd068d0b8f02f95231f49bc8df7b60777c85fc 100644 (file)
@@ -1,7 +1,9 @@
 ; Check that this test makes INDVAR and related stuff dead, because P[indvar]
 ; gets reduced, making INDVAR dead.
 
-; RUN: opt < %s -loop-reduce -S -default-data-layout="e-p:32:32:32" | not grep INDVAR
+; RUN: opt < %s -loop-reduce -S | not grep INDVAR
+
+target datalayout = "e-p:32:32:32-n:32"
 
 declare i1 @pred()
 
index 0a9fab0d5ea8d6564f31883b6084768e7efbc609..7547d83629299e99d90b76940112002b2df7e68a 100644 (file)
@@ -9,7 +9,7 @@
 
 ; mul uint %i, 3
 
-target datalayout = "e-p:32:32"
+target datalayout = "e-p:32:32-n:32"
 target triple = "i686-apple-darwin8"
 @flags2 = external global [8193 x i8], align 32                ; <[8193 x i8]*> [#uses=1]