diff options
author | Chris Lattner <sabre@nondot.org> | 2010-01-02 08:12:04 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-01-02 08:12:04 +0000 |
commit | 1f12e44b628679d003e99adc70e1ea0464e1971e (patch) | |
tree | 87cd85b662fec6d68c4b670c94c06699ad3c12c7 /test/Transforms/InstCombine/load-cmp.ll | |
parent | 79fa3cf451a74dd1cec0be2d77d7ea9737dffc69 (diff) |
Teach instcombine to fold compares of loads from constant
arrays with variable indices into a comparison of the index
with a constant. The most common occurrence of this that
I see by far is stuff like:
if ("foobar"[i] == '\0') ...
which we compile into: if (i == 6), saving a load and
materialization of the global address. This also exposes
loop trip count information to later passes in many cases.
This triggers hundreds of times in xalancbmk, which is where I first
noticed it, but it also triggers in many other apps. Here are a few
interesting ones from various apps:
@must_be_connected_without = internal constant [8 x i8*] [i8* getelementptr inbounds ([3 x i8]* @.str64320, i64 0, i64 0), i8* getelementptr inbounds ([3 x i8]* @.str27283, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8]* @.str71327, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8]* @.str72328, i64 0, i64 0), i8* getelementptr inbounds ([3 x i8]* @.str18274, i64 0, i64 0), i8* getelementptr inbounds ([6 x i8]* @.str11267, i64 0, i64 0), i8* getelementptr inbounds ([3 x i8]* @.str32288, i64 0, i64 0), i8* null], align 32 ; <[8 x i8*]*> [#uses=2]
%scevgep.i = getelementptr [8 x i8*]* @must_be_connected_without, i64 0, i64 %indvar.i ; <i8**> [#uses=1]
%17 = load ...
%18 = icmp eq i8* %17, null ; <i1> [#uses=1]
-> icmp eq i64 %indvar.i, 7
@yytable1095 = internal constant [84 x i8] c"\12\01(\05\06\07\08\09\0A\0B\0C\0D\0E1\0F\10\11266\1D: \10\11,-,0\03'\10\11B6\04\17&\18\1945\05\06\07\08\09\0A\0B\0C\0D\0E\1E\0F\10\11*\1A\1B\1C$3+>#%;<IJ=ADFEGH9KL\00\00\00C", align 32 ; <[84 x i8]*> [#uses=2]
%57 = getelementptr inbounds [84 x i8]* @yytable1095, i64 0, i64 %56 ; <i8*> [#uses=1]
%mode.0.in = getelementptr inbounds [9 x i32]* @mb_mode_table, i64 0, i64 %.pn ; <i32*> [#uses=1]
load ...
%64 = icmp eq i8 %58, 4 ; <i1> [#uses=1]
-> icmp eq i64 %.pn, 35 ; <i1> [#uses=0]
@gsm_DLB = internal constant [4 x i16] [i16 6554, i16 16384, i16 26214, i16 32767]
%scevgep.i = getelementptr [4 x i16]* @gsm_DLB, i64 0, i64 %indvar.i ; <i16*> [#uses=1]
%425 = load %scevgep.i
%426 = icmp eq i16 %425, -32768 ; <i1> [#uses=0]
-> false
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@92411 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Transforms/InstCombine/load-cmp.ll')
-rw-r--r-- | test/Transforms/InstCombine/load-cmp.ll | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/test/Transforms/InstCombine/load-cmp.ll b/test/Transforms/InstCombine/load-cmp.ll new file mode 100644 index 0000000000..f410939e70 --- /dev/null +++ b/test/Transforms/InstCombine/load-cmp.ll @@ -0,0 +1,25 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s + +@G16 = internal constant [10 x i16] [i16 35, i16 82, i16 69, i16 81, i16 85, + i16 73, i16 82, i16 69, i16 68, i16 0] + +define i1 @test1(i32 %X) { + %P = getelementptr [10 x i16]* @G16, i32 0, i32 %X + %Q = load i16* %P + %R = icmp eq i16 %Q, 0 + ret i1 %R +; CHECK: @test1 +; CHECK-NEXT: %R = icmp eq i32 %X, 9 +; CHECK-NEXT: ret i1 %R +} + +define i1 @test2(i32 %X) { + %P = getelementptr [10 x i16]* @G16, i32 0, i32 %X + %Q = load i16* %P + %R = icmp slt i16 %Q, 85 + ret i1 %R +; CHECK: @test2 +; CHECK-NEXT: %R = icmp ne i32 %X, 4 +; CHECK-NEXT: ret i1 %R +} + |