1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; Verify that calls to known string library functions declared with 3; incompatible signatures are handled gracefully and without aborting. 4; 5; RUN: opt < %s -passes=instcombine -S | FileCheck %s 6 7@a = constant [2 x i8] c"1\00" 8 9declare ptr @atoi(ptr) 10declare ptr @atol(ptr) 11declare ptr @atoll(ptr) 12 13define void @call_bad_ato(ptr %ps) { 14; CHECK-LABEL: @call_bad_ato( 15; CHECK-NEXT: [[IR:%.*]] = call ptr @atoi(ptr nonnull @a) 16; CHECK-NEXT: store ptr [[IR]], ptr [[PS:%.*]], align 8 17; CHECK-NEXT: [[LR:%.*]] = call ptr @atol(ptr nonnull @a) 18; CHECK-NEXT: [[PS1:%.*]] = getelementptr i8, ptr [[PS]], i64 8 19; CHECK-NEXT: store ptr [[LR]], ptr [[PS1]], align 8 20; CHECK-NEXT: [[LLR:%.*]] = call ptr @atol(ptr nonnull @a) 21; CHECK-NEXT: [[PS2:%.*]] = getelementptr i8, ptr [[PS]], i64 16 22; CHECK-NEXT: store ptr [[LLR]], ptr [[PS2]], align 8 23; CHECK-NEXT: ret void 24; 25 26 %ir = call ptr @atoi(ptr @a) 27 store ptr %ir, ptr %ps 28 29 %lr = call ptr @atol(ptr @a) 30 %ps1 = getelementptr ptr, ptr %ps, i32 1 31 store ptr %lr, ptr %ps1 32 33 %llr = call ptr @atol(ptr @a) 34 %ps2 = getelementptr ptr, ptr %ps, i32 2 35 store ptr %llr, ptr %ps2 36 37 ret void 38} 39 40 41declare ptr @strncasecmp(ptr, ptr) 42 43define ptr @call_bad_strncasecmp() { 44; CHECK-LABEL: @call_bad_strncasecmp( 45; CHECK-NEXT: [[CMP:%.*]] = call ptr @strncasecmp(ptr nonnull @a, ptr nonnull getelementptr inbounds nuw (i8, ptr @a, i64 1)) 46; CHECK-NEXT: ret ptr [[CMP]] 47; 48 %p1 = getelementptr [2 x i8], ptr @a, i32 0, i32 1 49 %cmp = call ptr @strncasecmp(ptr @a, ptr %p1) 50 ret ptr %cmp 51} 52 53 54declare i1 @strcoll(ptr, ptr, ptr) 55 56define i1 @call_bad_strcoll() { 57; CHECK-LABEL: @call_bad_strcoll( 58; CHECK-NEXT: [[I:%.*]] = call i1 @strcoll(ptr nonnull @a, ptr nonnull getelementptr inbounds nuw (i8, ptr @a, i64 1), ptr nonnull @a) 59; CHECK-NEXT: ret i1 [[I]] 60; 61 %p1 = getelementptr [2 x i8], ptr @a, i32 0, i32 1 62 %i = call i1 @strcoll(ptr @a, ptr %p1, ptr @a) 63 ret i1 %i 64} 65 66 67declare ptr @strndup(ptr) 68 69define ptr @call_bad_strndup() { 70; CHECK-LABEL: @call_bad_strndup( 71; CHECK-NEXT: [[D:%.*]] = call ptr @strndup(ptr nonnull @a) 72; CHECK-NEXT: ret ptr [[D]] 73; 74 %d = call ptr @strndup(ptr @a) 75 ret ptr %d 76} 77 78 79declare i1 @strtok(ptr, ptr, i1) 80 81define i1 @call_bad_strtok() { 82; CHECK-LABEL: @call_bad_strtok( 83; CHECK-NEXT: [[RET:%.*]] = call i1 @strtok(ptr nonnull @a, ptr nonnull getelementptr inbounds nuw (i8, ptr @a, i64 1), i1 false) 84; CHECK-NEXT: ret i1 [[RET]] 85; 86 %p1 = getelementptr [2 x i8], ptr @a, i32 0, i32 1 87 %ret = call i1 @strtok(ptr @a, ptr %p1, i1 0) 88 ret i1 %ret 89} 90 91 92 93declare i1 @strtok_r(ptr, ptr) 94 95define i1 @call_bad_strtok_r() { 96; CHECK-LABEL: @call_bad_strtok_r( 97; CHECK-NEXT: [[RET:%.*]] = call i1 @strtok_r(ptr nonnull @a, ptr nonnull getelementptr inbounds nuw (i8, ptr @a, i64 1)) 98; CHECK-NEXT: ret i1 [[RET]] 99; 100 %p1 = getelementptr [2 x i8], ptr @a, i32 0, i32 1 101 %ret = call i1 @strtok_r(ptr @a, ptr %p1) 102 ret i1 %ret 103} 104 105 106declare i32 @strtol(ptr, ptr) 107declare i32 @strtoul(ptr, ptr) 108 109declare i64 @strtoll(ptr, ptr) 110declare i64 @strtoull(ptr, ptr) 111 112define void @call_bad_strto(ptr %psi32, ptr %psi64) { 113; CHECK-LABEL: @call_bad_strto( 114; CHECK-NEXT: [[LR:%.*]] = call i32 @strtol(ptr nonnull @a, ptr null) 115; CHECK-NEXT: store i32 [[LR]], ptr [[PSI32:%.*]], align 4 116; CHECK-NEXT: [[ULR:%.*]] = call i32 @strtoul(ptr nonnull @a, ptr null) 117; CHECK-NEXT: [[PS1:%.*]] = getelementptr i8, ptr [[PSI32]], i64 4 118; CHECK-NEXT: store i32 [[ULR]], ptr [[PS1]], align 4 119; CHECK-NEXT: [[LLR:%.*]] = call i64 @strtoll(ptr nonnull @a, ptr null) 120; CHECK-NEXT: store i64 [[LLR]], ptr [[PSI64:%.*]], align 4 121; CHECK-NEXT: [[ULLR:%.*]] = call i64 @strtoull(ptr nonnull @a, ptr null) 122; CHECK-NEXT: [[PS3:%.*]] = getelementptr i8, ptr [[PSI64]], i64 24 123; CHECK-NEXT: store i64 [[ULLR]], ptr [[PS3]], align 4 124; CHECK-NEXT: ret void 125; 126 127 %lr = call i32 @strtol(ptr @a, ptr null) 128 store i32 %lr, ptr %psi32 129 130 %ulr = call i32 @strtoul(ptr @a, ptr null) 131 %ps1 = getelementptr i32, ptr %psi32, i32 1 132 store i32 %ulr, ptr %ps1 133 134 %llr = call i64 @strtoll(ptr @a, ptr null) 135 store i64 %llr, ptr %psi64 136 137 %ullr = call i64 @strtoull(ptr @a, ptr null) 138 %ps3 = getelementptr i64, ptr %psi64, i32 3 139 store i64 %ullr, ptr %ps3 140 141 ret void 142} 143 144 145declare ptr @strxfrm(ptr, ptr) 146 147define ptr @call_bad_strxfrm() { 148; CHECK-LABEL: @call_bad_strxfrm( 149; CHECK-NEXT: [[RET:%.*]] = call ptr @strxfrm(ptr nonnull @a, ptr nonnull getelementptr inbounds nuw (i8, ptr @a, i64 1)) 150; CHECK-NEXT: ret ptr [[RET]] 151; 152 %p1 = getelementptr [2 x i8], ptr @a, i32 0, i32 1 153 %ret = call ptr @strxfrm(ptr @a, ptr %p1) 154 ret ptr %ret 155} 156