Home | History | Annotate | Download | only in InstCombine
      1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
      2 ; Test that the memchr library call simplifier works correctly.
      3 ; RUN: opt < %s -instcombine -S | FileCheck %s
      4 
      5 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"
      6 
      7 @hello = constant [14 x i8] c"hello world\5Cn\00"
      8 @hellonull = constant [14 x i8] c"hello\00world\5Cn\00"
      9 @null = constant [1 x i8] zeroinitializer
     10 @newlines = constant [3 x i8] c"\0D\0A\00"
     11 @single = constant [2 x i8] c"\1F\00"
     12 @spaces = constant [4 x i8] c" \0D\0A\00"
     13 @negative = constant [3 x i8] c"\FF\FE\00"
     14 @chp = global i8* zeroinitializer
     15 
     16 declare i8* @memchr(i8*, i32, i32)
     17 
     18 define void @test1() {
     19 ; CHECK-LABEL: @test1(
     20 ; CHECK-NEXT:    store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 6), i8** @chp, align 4
     21 ; CHECK-NEXT:    ret void
     22 ;
     23   %str = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0
     24   %dst = call i8* @memchr(i8* %str, i32 119, i32 14)
     25   store i8* %dst, i8** @chp
     26   ret void
     27 }
     28 
     29 define void @test2() {
     30 ; CHECK-LABEL: @test2(
     31 ; CHECK-NEXT:    store i8* null, i8** @chp, align 4
     32 ; CHECK-NEXT:    ret void
     33 ;
     34   %str = getelementptr [1 x i8], [1 x i8]* @null, i32 0, i32 0
     35   %dst = call i8* @memchr(i8* %str, i32 119, i32 1)
     36   store i8* %dst, i8** @chp
     37   ret void
     38 }
     39 
     40 define void @test3() {
     41 ; CHECK-LABEL: @test3(
     42 ; CHECK-NEXT:    store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 13), i8** @chp, align 4
     43 ; CHECK-NEXT:    ret void
     44 ;
     45   %src = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0
     46   %dst = call i8* @memchr(i8* %src, i32 0, i32 14)
     47   store i8* %dst, i8** @chp
     48   ret void
     49 }
     50 
     51 define void @test4(i32 %chr) {
     52 ; CHECK-LABEL: @test4(
     53 ; CHECK-NEXT:    [[DST:%.*]] = call i8* @memchr(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 0), i32 %chr, i32 14)
     54 ; CHECK-NEXT:    store i8* [[DST]], i8** @chp, align 4
     55 ; CHECK-NEXT:    ret void
     56 ;
     57   %src = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0
     58   %dst = call i8* @memchr(i8* %src, i32 %chr, i32 14)
     59   store i8* %dst, i8** @chp
     60   ret void
     61 }
     62 
     63 define void @test5() {
     64 ; CHECK-LABEL: @test5(
     65 ; CHECK-NEXT:    store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 13), i8** @chp, align 4
     66 ; CHECK-NEXT:    ret void
     67 ;
     68   %src = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0
     69   %dst = call i8* @memchr(i8* %src, i32 65280, i32 14)
     70   store i8* %dst, i8** @chp
     71   ret void
     72 }
     73 
     74 define void @test6() {
     75 ; CHECK-LABEL: @test6(
     76 ; CHECK-NEXT:    store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 6), i8** @chp, align 4
     77 ; CHECK-NEXT:    ret void
     78 ;
     79   %src = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0
     80 ; Overflow, but we still find the right thing.
     81   %dst = call i8* @memchr(i8* %src, i32 119, i32 100)
     82   store i8* %dst, i8** @chp
     83   ret void
     84 }
     85 
     86 define void @test7() {
     87 ; CHECK-LABEL: @test7(
     88 ; CHECK-NEXT:    store i8* null, i8** @chp, align 4
     89 ; CHECK-NEXT:    ret void
     90 ;
     91   %src = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0
     92 ; Overflow
     93   %dst = call i8* @memchr(i8* %src, i32 120, i32 100)
     94   store i8* %dst, i8** @chp
     95   ret void
     96 }
     97 
     98 define void @test8() {
     99 ; CHECK-LABEL: @test8(
    100 ; CHECK-NEXT:    store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hellonull, i32 0, i32 6), i8** @chp, align 4
    101 ; CHECK-NEXT:    ret void
    102 ;
    103   %str = getelementptr [14 x i8], [14 x i8]* @hellonull, i32 0, i32 0
    104   %dst = call i8* @memchr(i8* %str, i32 119, i32 14)
    105   store i8* %dst, i8** @chp
    106   ret void
    107 }
    108 
    109 define void @test9() {
    110 ; CHECK-LABEL: @test9(
    111 ; CHECK-NEXT:    store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hellonull, i32 0, i32 6), i8** @chp, align 4
    112 ; CHECK-NEXT:    ret void
    113 ;
    114   %str = getelementptr [14 x i8], [14 x i8]* @hellonull, i32 0, i32 2
    115   %dst = call i8* @memchr(i8* %str, i32 119, i32 12)
    116   store i8* %dst, i8** @chp
    117   ret void
    118 }
    119 
    120 define void @test10() {
    121 ; CHECK-LABEL: @test10(
    122 ; CHECK-NEXT:    store i8* null, i8** @chp, align 4
    123 ; CHECK-NEXT:    ret void
    124 ;
    125   %str = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0
    126   %dst = call i8* @memchr(i8* %str, i32 119, i32 6)
    127   store i8* %dst, i8** @chp
    128   ret void
    129 }
    130 
    131 ; Check transformation memchr("\r\n", C, 2) != nullptr -> (C & 9216) != 0
    132 define i1 @test11(i32 %C) {
    133 ; CHECK-LABEL: @test11(
    134 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 %C to i16
    135 ; CHECK-NEXT:    [[MEMCHR_BOUNDS:%.*]] = icmp ult i16 [[TMP1]], 16
    136 ; CHECK-NEXT:    [[TMP2:%.*]] = shl i16 1, [[TMP1]]
    137 ; CHECK-NEXT:    [[TMP3:%.*]] = and i16 [[TMP2]], 9216
    138 ; CHECK-NEXT:    [[MEMCHR_BITS:%.*]] = icmp ne i16 [[TMP3]], 0
    139 ; CHECK-NEXT:    [[MEMCHR:%.*]] = and i1 [[MEMCHR:%.*]].bounds, [[MEMCHR:%.*]].bits
    140 ; CHECK-NEXT:    ret i1 [[MEMCHR]]
    141 ;
    142   %dst = call i8* @memchr(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @newlines, i64 0, i64 0), i32 %C, i32 2)
    143   %cmp = icmp ne i8* %dst, null
    144   ret i1 %cmp
    145 }
    146 
    147 ; No 64 bits here
    148 define i1 @test12(i32 %C) {
    149 ; CHECK-LABEL: @test12(
    150 ; CHECK-NEXT:    [[DST:%.*]] = call i8* @memchr(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @spaces, i32 0, i32 0), i32 %C, i32 3)
    151 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8* [[DST]], null
    152 ; CHECK-NEXT:    ret i1 [[CMP]]
    153 ;
    154   %dst = call i8* @memchr(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @spaces, i64 0, i64 0), i32 %C, i32 3)
    155   %cmp = icmp ne i8* %dst, null
    156   ret i1 %cmp
    157 }
    158 
    159 define i1 @test13(i32 %C) {
    160 ; CHECK-LABEL: @test13(
    161 ; CHECK-NEXT:    [[MEMCHR_BOUNDS:%.*]] = icmp ult i32 %C, 32
    162 ; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 1, %C
    163 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], -2147483647
    164 ; CHECK-NEXT:    [[MEMCHR_BITS:%.*]] = icmp ne i32 [[TMP2]], 0
    165 ; CHECK-NEXT:    [[MEMCHR:%.*]] = and i1 [[MEMCHR:%.*]].bounds, [[MEMCHR:%.*]].bits
    166 ; CHECK-NEXT:    ret i1 [[MEMCHR]]
    167 ;
    168   %dst = call i8* @memchr(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @single, i64 0, i64 0), i32 %C, i32 2)
    169   %cmp = icmp ne i8* %dst, null
    170   ret i1 %cmp
    171 }
    172 
    173 define i1 @test14(i32 %C) {
    174 ; CHECK-LABEL: @test14(
    175 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 %C, 31
    176 ; CHECK-NEXT:    ret i1 [[TMP1]]
    177 ;
    178   %dst = call i8* @memchr(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @single, i64 0, i64 0), i32 %C, i32 1)
    179   %cmp = icmp ne i8* %dst, null
    180   ret i1 %cmp
    181 }
    182 
    183 define i1 @test15(i32 %C) {
    184 ; CHECK-LABEL: @test15(
    185 ; CHECK-NEXT:    [[DST:%.*]] = call i8* @memchr(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @negative, i32 0, i32 0), i32 %C, i32 3)
    186 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8* [[DST]], null
    187 ; CHECK-NEXT:    ret i1 [[CMP]]
    188 ;
    189   %dst = call i8* @memchr(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @negative, i64 0, i64 0), i32 %C, i32 3)
    190   %cmp = icmp ne i8* %dst, null
    191   ret i1 %cmp
    192 }
    193