[llvm-commits] [llvm] r164784 - in /llvm/trunk: lib/Transforms/Utils/SimplifyCFG.cpp test/Transforms/SimplifyCFG/switch_to_lookup_table.ll
Benjamin Kramer
benny.kra at googlemail.com
Thu Sep 27 11:29:58 PDT 2012
Author: d0k
Date: Thu Sep 27 13:29:58 2012
New Revision: 164784
URL: http://llvm.org/viewvc/llvm-project?rev=164784&view=rev
Log:
Fix a integer overflow in SimplifyCFG's look up table formation logic.
If the width is very large it gets truncated from uint64_t to uint32_t when
passed to TD->fitsInLegalInteger. The truncated value can fit in a register.
This manifested in massive memory usage or crashes (PR13946).
Modified:
llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
llvm/trunk/test/Transforms/SimplifyCFG/switch_to_lookup_table.ll
Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=164784&r1=164783&r2=164784&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Thu Sep 27 13:29:58 2012
@@ -3414,6 +3414,10 @@
return false;
// FIXME: If the type is wider than it needs to be, e.g. i8 but all values
// are <= 15, we could try to narrow the type.
+
+ // Avoid overflow, fitsInLegalInteger uses unsigned int for the width.
+ if (TableSize >= UINT_MAX/IT->getBitWidth())
+ return false;
return TD->fitsInLegalInteger(TableSize * IT->getBitWidth());
}
Modified: llvm/trunk/test/Transforms/SimplifyCFG/switch_to_lookup_table.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/switch_to_lookup_table.ll?rev=164784&r1=164783&r2=164784&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SimplifyCFG/switch_to_lookup_table.ll (original)
+++ llvm/trunk/test/Transforms/SimplifyCFG/switch_to_lookup_table.ll Thu Sep 27 13:29:58 2012
@@ -231,3 +231,41 @@
; CHECK-NEXT: %lor.ext = zext i1 %1 to i32
; CHECK-NEXT: ret i32 %lor.ext
}
+
+; PR13946
+define i32 @overflow(i32 %type) nounwind {
+entry:
+ switch i32 %type, label %sw.default [
+ i32 -2147483648, label %sw.bb
+ i32 0, label %sw.bb
+ i32 1, label %sw.bb1
+ i32 2, label %sw.bb2
+ i32 -2147483645, label %sw.bb3
+ i32 3, label %sw.bb3
+ ]
+
+sw.bb:
+ br label %if.end
+
+sw.bb1:
+ br label %if.end
+
+sw.bb2:
+ br label %if.end
+
+sw.bb3:
+ br label %if.end
+
+sw.default:
+ br label %if.end
+
+if.else:
+ br label %if.end
+
+if.end:
+ %dirent_type.0 = phi i32 [ 3, %sw.default ], [ 6, %sw.bb3 ], [ 5, %sw.bb2 ], [ 0, %sw.bb1 ], [ 3, %sw.bb ], [ 0, %if.else ]
+ ret i32 %dirent_type.0
+; CHECK: define i32 @overflow
+; CHECK: switch
+; CHECK: phi
+}
More information about the llvm-commits
mailing list