Home | History | Annotate | Download | only in InstCombine
      1 ; Test that the strchr library call simplifier works correctly.
      2 ; RUN: opt < %s -instcombine -S | FileCheck %s
      3 
      4 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-f80:128:128-n8:16:32"
      5 
      6 @hello = constant [14 x i8] c"hello world\5Cn\00"
      7 @null = constant [1 x i8] zeroinitializer
      8 @newlines = constant [3 x i8] c"\0D\0A\00"
      9 @chp = global i8* zeroinitializer
     10 
     11 declare i8* @strchr(i8*, i32)
     12 
     13 define void @test_simplify1() {
     14 ; CHECK: store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 6)
     15 ; CHECK-NOT: call i8* @strchr
     16 ; CHECK: ret void
     17 
     18   %str = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0
     19   %dst = call i8* @strchr(i8* %str, i32 119)
     20   store i8* %dst, i8** @chp
     21   ret void
     22 }
     23 
     24 define void @test_simplify2() {
     25 ; CHECK: store i8* null, i8** @chp, align 4
     26 ; CHECK-NOT: call i8* @strchr
     27 ; CHECK: ret void
     28 
     29   %str = getelementptr [1 x i8], [1 x i8]* @null, i32 0, i32 0
     30   %dst = call i8* @strchr(i8* %str, i32 119)
     31   store i8* %dst, i8** @chp
     32   ret void
     33 }
     34 
     35 define void @test_simplify3() {
     36 ; CHECK: store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 13)
     37 ; CHECK-NOT: call i8* @strchr
     38 ; CHECK: ret void
     39 
     40   %src = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0
     41   %dst = call i8* @strchr(i8* %src, i32 0)
     42   store i8* %dst, i8** @chp
     43   ret void
     44 }
     45 
     46 define void @test_simplify4(i32 %chr) {
     47 ; CHECK: call i8* @memchr
     48 ; CHECK-NOT: call i8* @strchr
     49 ; CHECK: ret void
     50 
     51   %src = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0
     52   %dst = call i8* @strchr(i8* %src, i32 %chr)
     53   store i8* %dst, i8** @chp
     54   ret void
     55 }
     56 
     57 define void @test_simplify5() {
     58 ; CHECK: store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 13)
     59 ; CHECK-NOT: call i8* @strchr
     60 ; CHECK: ret void
     61 
     62   %src = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0
     63   %dst = call i8* @strchr(i8* %src, i32 65280)
     64   store i8* %dst, i8** @chp
     65   ret void
     66 }
     67 
     68 ; Check transformation strchr(p, 0) -> p + strlen(p)
     69 define void @test_simplify6(i8* %str) {
     70 ; CHECK: %strlen = call i32 @strlen(i8* %str)
     71 ; CHECK-NOT: call i8* @strchr
     72 ; CHECK: %strchr = getelementptr i8, i8* %str, i32 %strlen
     73 ; CHECK: store i8* %strchr, i8** @chp, align 4
     74 ; CHECK: ret void
     75 
     76   %dst = call i8* @strchr(i8* %str, i32 0)
     77   store i8* %dst, i8** @chp
     78   ret void
     79 }
     80 
     81 ; Check transformation strchr("\r\n", C) != nullptr -> (C & 9217) != 0
     82 define i1 @test_simplify7(i32 %C) {
     83 ; CHECK-LABEL: @test_simplify7
     84 ; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 %C to i16
     85 ; CHECK-NEXT: %memchr.bounds = icmp ult i16 [[TRUNC]], 16
     86 ; CHECK-NEXT: [[SHL:%.*]] = shl i16 1, [[TRUNC]]
     87 ; CHECK-NEXT: [[AND:%.*]] = and i16 [[SHL]], 9217
     88 ; CHECK-NEXT: %memchr.bits = icmp ne i16 [[AND]], 0
     89 ; CHECK-NEXT: %memchr1 = and i1 %memchr.bounds, %memchr.bits
     90 ; CHECK-NEXT: ret i1 %memchr1
     91 
     92   %dst = call i8* @strchr(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @newlines, i64 0, i64 0), i32 %C)
     93   %cmp = icmp ne i8* %dst, null
     94   ret i1 %cmp
     95 }
     96