[llvm-commits] [llvm] r75680 - in /llvm/trunk: lib/Analysis/ScalarEvolutionExpander.cpp test/Transforms/IndVarSimplify/max-pointer.ll

Dan Gohman gohman at apple.com
Tue Jul 14 13:57:35 PDT 2009


Author: djg
Date: Tue Jul 14 15:57:04 2009
New Revision: 75680

URL: http://llvm.org/viewvc/llvm-project?rev=75680&view=rev
Log:
Fix the expansion of umax and smax in the case where one or more of
the operands have pointer type, so that the resulting type matches
the original SCEV type, and so that unnecessary ptrtoints are
avoided in common cases.

Added:
    llvm/trunk/test/Transforms/IndVarSimplify/max-pointer.ll
Modified:
    llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp

Modified: llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp?rev=75680&r1=75679&r2=75680&view=diff

==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp Tue Jul 14 15:57:04 2009
@@ -609,9 +609,15 @@
 }
 
 Value *SCEVExpander::visitSMaxExpr(const SCEVSMaxExpr *S) {
-  const Type *Ty = SE.getEffectiveSCEVType(S->getType());
-  Value *LHS = expandCodeFor(S->getOperand(0), Ty);
-  for (unsigned i = 1; i < S->getNumOperands(); ++i) {
+  Value *LHS = expand(S->getOperand(S->getNumOperands()-1));
+  const Type *Ty = LHS->getType();
+  for (int i = S->getNumOperands()-2; i >= 0; --i) {
+    // In the case of mixed integer and pointer types, do the
+    // rest of the comparisons as integer.
+    if (S->getOperand(i)->getType() != Ty) {
+      Ty = SE.getEffectiveSCEVType(Ty);
+      LHS = InsertNoopCastOfTo(LHS, Ty);
+    }
     Value *RHS = expandCodeFor(S->getOperand(i), Ty);
     Value *ICmp = Builder.CreateICmpSGT(LHS, RHS, "tmp");
     InsertedValues.insert(ICmp);
@@ -619,13 +625,23 @@
     InsertedValues.insert(Sel);
     LHS = Sel;
   }
+  // In the case of mixed integer and pointer types, cast the
+  // final result back to the pointer type.
+  if (LHS->getType() != S->getType())
+    LHS = InsertNoopCastOfTo(LHS, S->getType());
   return LHS;
 }
 
 Value *SCEVExpander::visitUMaxExpr(const SCEVUMaxExpr *S) {
-  const Type *Ty = SE.getEffectiveSCEVType(S->getType());
-  Value *LHS = expandCodeFor(S->getOperand(0), Ty);
-  for (unsigned i = 1; i < S->getNumOperands(); ++i) {
+  Value *LHS = expand(S->getOperand(S->getNumOperands()-1));
+  const Type *Ty = LHS->getType();
+  for (int i = S->getNumOperands()-2; i >= 0; --i) {
+    // In the case of mixed integer and pointer types, do the
+    // rest of the comparisons as integer.
+    if (S->getOperand(i)->getType() != Ty) {
+      Ty = SE.getEffectiveSCEVType(Ty);
+      LHS = InsertNoopCastOfTo(LHS, Ty);
+    }
     Value *RHS = expandCodeFor(S->getOperand(i), Ty);
     Value *ICmp = Builder.CreateICmpUGT(LHS, RHS, "tmp");
     InsertedValues.insert(ICmp);
@@ -633,6 +649,10 @@
     InsertedValues.insert(Sel);
     LHS = Sel;
   }
+  // In the case of mixed integer and pointer types, cast the
+  // final result back to the pointer type.
+  if (LHS->getType() != S->getType())
+    LHS = InsertNoopCastOfTo(LHS, S->getType());
   return LHS;
 }
 

Added: llvm/trunk/test/Transforms/IndVarSimplify/max-pointer.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/max-pointer.ll?rev=75680&view=auto

==============================================================================
--- llvm/trunk/test/Transforms/IndVarSimplify/max-pointer.ll (added)
+++ llvm/trunk/test/Transforms/IndVarSimplify/max-pointer.ll Tue Jul 14 15:57:04 2009
@@ -0,0 +1,145 @@
+; RUN: llvm-as < %s | opt -indvars | llvm-dis > %t
+; 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"
+
+	%struct.CKenCodeCodec = type <{ i8 }>
+
+define void @foo(i8* %str1Ptr, i8* %str2Ptr, i8* %inLastBytePtr) nounwind {
+entry:
+	%0 = icmp ult i8* %str2Ptr, %str1Ptr		; <i1> [#uses=1]
+	%str2Ptr_addr.0 = select i1 %0, i8* %str1Ptr, i8* %str2Ptr		; <i8*> [#uses=1]
+	br label %bb2
+
+bb2:		; preds = %bb2, %entry
+	%str2Ptr_addr.1 = phi i8* [ %str2Ptr_addr.0, %entry ], [ %1, %bb2 ]		; <i8*> [#uses=1]
+	%1 = getelementptr i8* %str2Ptr_addr.1, i64 1		; <i8*> [#uses=2]
+	%2 = icmp ult i8* %1, %inLastBytePtr		; <i1> [#uses=0]
+	br i1 false, label %bb2, label %return
+
+return:		; preds = %bb2
+	ret void
+}
+
+define void @bar(i8* %str1Ptr, i64 %s, i8* %inLastBytePtr) nounwind {
+entry:
+        %str2Ptr = inttoptr i64 %s to i8*
+	%0 = icmp ult i8* %str2Ptr, %str1Ptr		; <i1> [#uses=1]
+	%str2Ptr_addr.0 = select i1 %0, i8* %str1Ptr, i8* %str2Ptr		; <i8*> [#uses=1]
+	br label %bb2
+
+bb2:		; preds = %bb2, %entry
+	%str2Ptr_addr.1 = phi i8* [ %str2Ptr_addr.0, %entry ], [ %1, %bb2 ]		; <i8*> [#uses=1]
+	%1 = getelementptr i8* %str2Ptr_addr.1, i64 1		; <i8*> [#uses=2]
+	%2 = icmp ult i8* %1, %inLastBytePtr		; <i1> [#uses=0]
+	br i1 false, label %bb2, label %return
+
+return:		; preds = %bb2
+	ret void
+}
+
+define void @qux(i64 %t, i64 %s, i8* %inLastBytePtr) nounwind {
+entry:
+        %str1Ptr = inttoptr i64 %t to i8*
+        %str2Ptr = inttoptr i64 %s to i8*
+	%0 = icmp ult i8* %str2Ptr, %str1Ptr		; <i1> [#uses=1]
+	%str2Ptr_addr.0 = select i1 %0, i8* %str1Ptr, i8* %str2Ptr		; <i8*> [#uses=1]
+	br label %bb2
+
+bb2:		; preds = %bb2, %entry
+	%str2Ptr_addr.1 = phi i8* [ %str2Ptr_addr.0, %entry ], [ %1, %bb2 ]		; <i8*> [#uses=1]
+	%1 = getelementptr i8* %str2Ptr_addr.1, i64 1		; <i8*> [#uses=2]
+	%2 = icmp ult i8* %1, %inLastBytePtr		; <i1> [#uses=0]
+	br i1 false, label %bb2, label %return
+
+return:		; preds = %bb2
+	ret void
+}
+
+define void @vor(i64 %t, i8* %str2Ptr, i8* %inLastBytePtr) nounwind {
+entry:
+        %str1Ptr = inttoptr i64 %t to i8*
+	%0 = icmp ult i8* %str2Ptr, %str1Ptr		; <i1> [#uses=1]
+	%str2Ptr_addr.0 = select i1 %0, i8* %str1Ptr, i8* %str2Ptr		; <i8*> [#uses=1]
+	br label %bb2
+
+bb2:		; preds = %bb2, %entry
+	%str2Ptr_addr.1 = phi i8* [ %str2Ptr_addr.0, %entry ], [ %1, %bb2 ]		; <i8*> [#uses=1]
+	%1 = getelementptr i8* %str2Ptr_addr.1, i64 1		; <i8*> [#uses=2]
+	%2 = icmp ult i8* %1, %inLastBytePtr		; <i1> [#uses=0]
+	br i1 false, label %bb2, label %return
+
+return:		; preds = %bb2
+	ret void
+}
+
+define void @sfoo(i8* %str1Ptr, i8* %str2Ptr, i8* %inLastBytePtr) nounwind {
+entry:
+	%0 = icmp slt i8* %str2Ptr, %str1Ptr		; <i1> [#uses=1]
+	%str2Ptr_addr.0 = select i1 %0, i8* %str1Ptr, i8* %str2Ptr		; <i8*> [#uses=1]
+	br label %bb2
+
+bb2:		; preds = %bb2, %entry
+	%str2Ptr_addr.1 = phi i8* [ %str2Ptr_addr.0, %entry ], [ %1, %bb2 ]		; <i8*> [#uses=1]
+	%1 = getelementptr i8* %str2Ptr_addr.1, i64 1		; <i8*> [#uses=2]
+	%2 = icmp slt i8* %1, %inLastBytePtr		; <i1> [#uses=0]
+	br i1 false, label %bb2, label %return
+
+return:		; preds = %bb2
+	ret void
+}
+
+define void @sbar(i8* %str1Ptr, i64 %s, i8* %inLastBytePtr) nounwind {
+entry:
+        %str2Ptr = inttoptr i64 %s to i8*
+	%0 = icmp slt i8* %str2Ptr, %str1Ptr		; <i1> [#uses=1]
+	%str2Ptr_addr.0 = select i1 %0, i8* %str1Ptr, i8* %str2Ptr		; <i8*> [#uses=1]
+	br label %bb2
+
+bb2:		; preds = %bb2, %entry
+	%str2Ptr_addr.1 = phi i8* [ %str2Ptr_addr.0, %entry ], [ %1, %bb2 ]		; <i8*> [#uses=1]
+	%1 = getelementptr i8* %str2Ptr_addr.1, i64 1		; <i8*> [#uses=2]
+	%2 = icmp slt i8* %1, %inLastBytePtr		; <i1> [#uses=0]
+	br i1 false, label %bb2, label %return
+
+return:		; preds = %bb2
+	ret void
+}
+
+define void @squx(i64 %t, i64 %s, i8* %inLastBytePtr) nounwind {
+entry:
+        %str1Ptr = inttoptr i64 %t to i8*
+        %str2Ptr = inttoptr i64 %s to i8*
+	%0 = icmp slt i8* %str2Ptr, %str1Ptr		; <i1> [#uses=1]
+	%str2Ptr_addr.0 = select i1 %0, i8* %str1Ptr, i8* %str2Ptr		; <i8*> [#uses=1]
+	br label %bb2
+
+bb2:		; preds = %bb2, %entry
+	%str2Ptr_addr.1 = phi i8* [ %str2Ptr_addr.0, %entry ], [ %1, %bb2 ]		; <i8*> [#uses=1]
+	%1 = getelementptr i8* %str2Ptr_addr.1, i64 1		; <i8*> [#uses=2]
+	%2 = icmp slt i8* %1, %inLastBytePtr		; <i1> [#uses=0]
+	br i1 false, label %bb2, label %return
+
+return:		; preds = %bb2
+	ret void
+}
+
+define void @svor(i64 %t, i8* %str2Ptr, i8* %inLastBytePtr) nounwind {
+entry:
+        %str1Ptr = inttoptr i64 %t to i8*
+	%0 = icmp slt i8* %str2Ptr, %str1Ptr		; <i1> [#uses=1]
+	%str2Ptr_addr.0 = select i1 %0, i8* %str1Ptr, i8* %str2Ptr		; <i8*> [#uses=1]
+	br label %bb2
+
+bb2:		; preds = %bb2, %entry
+	%str2Ptr_addr.1 = phi i8* [ %str2Ptr_addr.0, %entry ], [ %1, %bb2 ]		; <i8*> [#uses=1]
+	%1 = getelementptr i8* %str2Ptr_addr.1, i64 1		; <i8*> [#uses=2]
+	%2 = icmp slt i8* %1, %inLastBytePtr		; <i1> [#uses=0]
+	br i1 false, label %bb2, label %return
+
+return:		; preds = %bb2
+	ret void
+}
+
+





More information about the llvm-commits mailing list