[llvm-commits] CVS: llvm-gcc/gcc/llvm-expand.c llvm-representation.c llvm-representation.h

Chris Lattner lattner at cs.uiuc.edu
Tue Nov 29 10:25:16 PST 2005



Changes in directory llvm-gcc/gcc:

llvm-expand.c updated: 1.117 -> 1.118
llvm-representation.c updated: 1.20 -> 1.21
llvm-representation.h updated: 1.19 -> 1.20
---
Log message:

Allow switch statements on long-long values to be correctly handled.  This
fixes PR671: http://llvm.cs.uiuc.edu/PR671  and llvm-test/SingleSource/UnitTests/2005-11-29-LongSwitch.c


---
Diffs of the changes:  (+25 -11)

 llvm-expand.c         |   23 ++++++++++++++---------
 llvm-representation.c |   11 ++++++++++-
 llvm-representation.h |    2 +-
 3 files changed, 25 insertions(+), 11 deletions(-)


Index: llvm-gcc/gcc/llvm-expand.c
diff -u llvm-gcc/gcc/llvm-expand.c:1.117 llvm-gcc/gcc/llvm-expand.c:1.118
--- llvm-gcc/gcc/llvm-expand.c:1.117	Wed Sep 28 02:16:59 2005
+++ llvm-gcc/gcc/llvm-expand.c	Tue Nov 29 12:25:04 2005
@@ -2022,8 +2022,8 @@
     add_scope_stack(Fn, &Fn->ExpandInfo->InnermostCaseScope, CASE_NESTING);
   llvm_instruction *SI = llvm_instruction_new(VoidTy, "", O_Switch, 2);
   llvm_value *Val = llvm_expand_expr(Fn, expr, 0);
-
-  SI->Operands[0] = cast_if_type_not_equal(Fn, Val, UIntTy);
+  assert(llvm_type_is_integral(Val->Ty) && "Not an integer switch expr!");
+  SI->Operands[0] = Val;
 
   append_inst(Fn, SI);
   thiscase->x.switchblock.SwitchInst = SI;
@@ -2083,6 +2083,15 @@
   pop_and_free_scope_stack(Fn, &Fn->ExpandInfo->InnermostCaseScope);
 }
 
+static unsigned long long getIntCstAsLongLong(tree V) {
+  unsigned HOST_WIDE_INT HI = (unsigned HOST_WIDE_INT)TREE_INT_CST_HIGH(V);
+  unsigned HOST_WIDE_INT LO = (unsigned HOST_WIDE_INT)TREE_INT_CST_LOW(V);
+  if (sizeof(LO) == 8) return LO;
+  
+  assert(sizeof(LO) == 4 && "64 and 32 bit HOST_WIDE_INT's supported!");
+  return ((long long)(unsigned)HI << 32) | (long long)(unsigned)LO;
+}
+
 /* Add a case label to the current switch statement.  This could be a range of
    case values to insert.  Handle them as appropriate.
  */
@@ -2091,7 +2100,7 @@
   llvm_nesting *thiscase = Fn->ExpandInfo->InnermostCaseScope;
   llvm_instruction *SwitchInst;
   llvm_basicblock *Block = getLabelDeclBlock(label);
-  int Low, High;
+  long long Low, High;
 
   assert(thiscase && "Case label not in case statement!");
   SwitchInst = thiscase->x.switchblock.SwitchInst;
@@ -2111,12 +2120,8 @@
     }
   }
 
-  if ((TREE_INT_CST_HIGH(low) != 0 || TREE_INT_CST_HIGH(high) != 0) &&
-      (TREE_INT_CST_HIGH(low) != -1 || TREE_INT_CST_HIGH(high) != -1))
-    LLVM_TODO_TREE(label); /* Cannot handle case values this large! */
-
-  Low = (int)TREE_INT_CST_LOW(low);
-  High = (int)TREE_INT_CST_LOW(high);
+  Low = getIntCstAsLongLong(low);
+  High = getIntCstAsLongLong(high);
 
   for (; Low != High+1; ++Low) {
     llvm_switch_case *NewCase = xmalloc(sizeof(llvm_switch_case));


Index: llvm-gcc/gcc/llvm-representation.c
diff -u llvm-gcc/gcc/llvm-representation.c:1.20 llvm-gcc/gcc/llvm-representation.c:1.21
--- llvm-gcc/gcc/llvm-representation.c:1.20	Sat Sep 24 03:33:56 2005
+++ llvm-gcc/gcc/llvm-representation.c	Tue Nov 29 12:25:04 2005
@@ -708,7 +708,16 @@
     fprintf(F, " [");
 
     for (; C; C = C->Next) {
-      fprintf(F, "\n\t\tuint %u, ", C->Value);
+      switch (Operand->Ty->ID) {
+      case UByteTyID:  fprintf(F, "\n\t\tubyte %u, ", (unsigned char)C->Value); break;
+      case SByteTyID:  fprintf(F, "\n\t\tsbyte %d, ", (signed char)C->Value); break;
+      case UShortTyID: fprintf(F, "\n\t\tushort %u, ", (unsigned short)C->Value); break;
+      case ShortTyID:  fprintf(F, "\n\t\tshort %d, ", (signed short)C->Value); break;
+      case UIntTyID:   fprintf(F, "\n\t\tuint %u, ", (unsigned)C->Value); break;
+      case IntTyID:    fprintf(F, "\n\t\tint %d, ", (signed)C->Value); break;
+      case ULongTyID:  fprintf(F, "\n\t\tulong %llu, ", C->Value); break;
+      case LongTyID:   fprintf(F, "\n\t\tlong %lld, ", C->Value); break;
+      }
       llvm_value_print_operand(D2V(C->Dest), 1, F);
     }
     fprintf(F, "\n\t]");


Index: llvm-gcc/gcc/llvm-representation.h
diff -u llvm-gcc/gcc/llvm-representation.h:1.19 llvm-gcc/gcc/llvm-representation.h:1.20
--- llvm-gcc/gcc/llvm-representation.h:1.19	Thu Jul 28 13:50:28 2005
+++ llvm-gcc/gcc/llvm-representation.h	Tue Nov 29 12:25:04 2005
@@ -154,7 +154,7 @@
 
 typedef struct llvm_switch_case {
   struct llvm_switch_case *Next;
-  unsigned Value;
+  unsigned long long Value;
   struct llvm_basicblock *Dest;
 } llvm_switch_case;
 






More information about the llvm-commits mailing list