121 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; Test that the strchr library call simplifier works correctly.3; RUN: opt < %s -passes=instcombine -S | FileCheck %s4 5target 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@null = constant [1 x i8] zeroinitializer9@newlines = constant [3 x i8] c"\0D\0A\00"10@chp = global ptr zeroinitializer11 12declare ptr @strchr(ptr, i32)13 14define void @test_simplify1() {15; CHECK-LABEL: @test_simplify1(16; CHECK-NEXT: store ptr getelementptr inbounds nuw (i8, ptr @hello, i32 6), ptr @chp, align 417; CHECK-NEXT: ret void18;19 20 %dst = call ptr @strchr(ptr @hello, i32 119)21 store ptr %dst, ptr @chp22 ret void23}24 25define void @test_simplify2() {26; CHECK-LABEL: @test_simplify2(27; CHECK-NEXT: store ptr null, ptr @chp, align 428; CHECK-NEXT: ret void29;30 31 %dst = call ptr @strchr(ptr @null, i32 119)32 store ptr %dst, ptr @chp33 ret void34}35 36define void @test_simplify3() {37; CHECK-LABEL: @test_simplify3(38; CHECK-NEXT: store ptr getelementptr inbounds nuw (i8, ptr @hello, i32 13), ptr @chp, align 439; CHECK-NEXT: ret void40;41 42 %dst = call ptr @strchr(ptr @hello, i32 0)43 store ptr %dst, ptr @chp44 ret void45}46 47define void @test_simplify4(i32 %chr) {48; CHECK-LABEL: @test_simplify4(49; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @memchr(ptr noundef nonnull dereferenceable(1) @hello, i32 [[CHR:%.*]], i32 14)50; CHECK-NEXT: store ptr [[MEMCHR]], ptr @chp, align 451; CHECK-NEXT: ret void52;53 54 %dst = call ptr @strchr(ptr @hello, i32 %chr)55 store ptr %dst, ptr @chp56 ret void57}58 59define void @test_simplify5() {60; CHECK-LABEL: @test_simplify5(61; CHECK-NEXT: store ptr getelementptr inbounds nuw (i8, ptr @hello, i32 13), ptr @chp, align 462; CHECK-NEXT: ret void63;64 65 %dst = call ptr @strchr(ptr @hello, i32 65280)66 store ptr %dst, ptr @chp67 ret void68}69 70; Check transformation strchr(p, 0) -> p + strlen(p)71define void @test_simplify6(ptr %str) {72; CHECK-LABEL: @test_simplify6(73; CHECK-NEXT: [[STRLEN:%.*]] = call i32 @strlen(ptr noundef nonnull dereferenceable(1) [[STR:%.*]])74; CHECK-NEXT: [[STRCHR:%.*]] = getelementptr inbounds i8, ptr [[STR]], i32 [[STRLEN]]75; CHECK-NEXT: store ptr [[STRCHR]], ptr @chp, align 476; CHECK-NEXT: ret void77;78 79 %dst = call ptr @strchr(ptr %str, i32 0)80 store ptr %dst, ptr @chp81 ret void82}83 84; Check transformation strchr("\r\n", C) != nullptr -> (C & 9217) != 085define i1 @test_simplify7(i32 %C) {86; CHECK-LABEL: @test_simplify7(87; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[C:%.*]] to i1688; CHECK-NEXT: [[TMP2:%.*]] = and i16 [[TMP1]], 25589; CHECK-NEXT: [[MEMCHR_BOUNDS:%.*]] = icmp samesign ult i16 [[TMP2]], 1690; CHECK-NEXT: [[TMP3:%.*]] = shl nuw i16 1, [[TMP2]]91; CHECK-NEXT: [[TMP4:%.*]] = and i16 [[TMP3]], 921792; CHECK-NEXT: [[MEMCHR_BITS:%.*]] = icmp ne i16 [[TMP4]], 093; CHECK-NEXT: [[MEMCHR1:%.*]] = select i1 [[MEMCHR_BOUNDS]], i1 [[MEMCHR_BITS]], i1 false94; CHECK-NEXT: ret i1 [[MEMCHR1]]95;96 97 %dst = call ptr @strchr(ptr @newlines, i32 %C)98 %cmp = icmp ne ptr %dst, null99 ret i1 %cmp100}101 102define ptr @test1(ptr %str, i32 %c) {103; CHECK-LABEL: @test1(104; CHECK-NEXT: [[RET:%.*]] = call ptr @strchr(ptr noundef nonnull dereferenceable(1) [[STR:%.*]], i32 [[C:%.*]])105; CHECK-NEXT: ret ptr [[RET]]106;107 108 %ret = call ptr @strchr(ptr %str, i32 %c)109 ret ptr %ret110}111 112define ptr @test2(ptr %str, i32 %c) null_pointer_is_valid {113; CHECK-LABEL: @test2(114; CHECK-NEXT: [[RET:%.*]] = call ptr @strchr(ptr noundef [[STR:%.*]], i32 [[C:%.*]])115; CHECK-NEXT: ret ptr [[RET]]116;117 118 %ret = call ptr @strchr(ptr %str, i32 %c)119 ret ptr %ret120}121