diff --git a/llvm/test/Transforms/InstCombine/X86/simplify-libcalls-memcmp.ll b/llvm/test/Transforms/InstCombine/X86/simplify-libcalls-memcmp.ll --- a/llvm/test/Transforms/InstCombine/X86/simplify-libcalls-memcmp.ll +++ b/llvm/test/Transforms/InstCombine/X86/simplify-libcalls-memcmp.ll @@ -10,13 +10,13 @@ @str = private unnamed_addr constant [6 x i8] c"abcde\00", align 1 -declare i32 @memcmp(i8*, i8*, i32) +declare i32 @memcmp(ptr, ptr, i32) define void @PR50850() { ; CHECK-LABEL: @PR50850( -; CHECK-NEXT: [[CALL:%.*]] = call i32 @memcmp(i8* bitcast (void ()* @PR50850 to i8*), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @str, i64 0, i64 0), i32 6) +; CHECK-NEXT: [[CALL:%.*]] = call i32 @memcmp(ptr nonnull @PR50850, ptr nonnull @str, i32 6) ; CHECK-NEXT: ret void ; - %call = call i32 @memcmp(i8* bitcast (void ()* @PR50850 to i8*), i8* bitcast ([6 x i8]* @str to i8*), i32 6) + %call = call i32 @memcmp(ptr @PR50850, ptr @str, i32 6) ret void } diff --git a/llvm/test/Transforms/InstCombine/memchr-2.ll b/llvm/test/Transforms/InstCombine/memchr-2.ll --- a/llvm/test/Transforms/InstCombine/memchr-2.ll +++ b/llvm/test/Transforms/InstCombine/memchr-2.ll @@ -4,7 +4,7 @@ ; Verify that memchr calls with constant arrays, or constant characters, ; or constant bounds are folded (or not) as expected. -declare i8* @memchr(i8*, i32, i64) +declare ptr @memchr(ptr, i32, i64) @ax = external global [0 x i8] @a12345 = constant [5 x i8] c"\01\02\03\04\05" @@ -13,123 +13,114 @@ ; Fold memchr(a12345, '\06', n) to null. -define i8* @fold_memchr_a12345_6_n(i64 %n) { +define ptr @fold_memchr_a12345_6_n(i64 %n) { ; CHECK-LABEL: @fold_memchr_a12345_6_n( -; CHECK-NEXT: ret i8* null +; CHECK-NEXT: ret ptr null ; - %ptr = getelementptr [5 x i8], [5 x i8]* @a12345, i32 0, i32 0 - %res = call i8* @memchr(i8* %ptr, i32 6, i64 %n) - ret i8* %res + %res = call ptr @memchr(ptr @a12345, i32 6, i64 %n) + ret ptr %res } ; Fold memchr(a12345, '\04', 2) to null. -define i8* @fold_memchr_a12345_4_2() { +define ptr @fold_memchr_a12345_4_2() { ; CHECK-LABEL: @fold_memchr_a12345_4_2( -; CHECK-NEXT: ret i8* null +; CHECK-NEXT: ret ptr null ; - %ptr = getelementptr [5 x i8], [5 x i8]* @a12345, i32 0, i32 0 - %res = call i8* @memchr(i8* %ptr, i32 4, i64 2) - ret i8* %res + %res = call ptr @memchr(ptr @a12345, i32 4, i64 2) + ret ptr %res } ; Fold memchr(a12345, '\04', 3) to null. -define i8* @fold_memchr_a12345_4_3() { +define ptr @fold_memchr_a12345_4_3() { ; CHECK-LABEL: @fold_memchr_a12345_4_3( -; CHECK-NEXT: ret i8* null +; CHECK-NEXT: ret ptr null ; - %ptr = getelementptr [5 x i8], [5 x i8]* @a12345, i32 0, i32 0 - %res = call i8* @memchr(i8* %ptr, i32 4, i64 3) - ret i8* %res + %res = call ptr @memchr(ptr @a12345, i32 4, i64 3) + ret ptr %res } ; Fold memchr(a12345, '\03', 3) to a12345 + 2. -define i8* @fold_memchr_a12345_3_3() { +define ptr @fold_memchr_a12345_3_3() { ; CHECK-LABEL: @fold_memchr_a12345_3_3( -; CHECK-NEXT: ret i8* getelementptr inbounds ([5 x i8], [5 x i8]* @a12345, i64 0, i64 2) +; CHECK-NEXT: ret ptr getelementptr inbounds ([5 x i8], ptr @a12345, i64 0, i64 2) ; - %ptr = getelementptr [5 x i8], [5 x i8]* @a12345, i32 0, i32 0 - %res = call i8* @memchr(i8* %ptr, i32 3, i64 3) - ret i8* %res + %res = call ptr @memchr(ptr @a12345, i32 3, i64 3) + ret ptr %res } ; Fold memchr(a12345, '\03', 9) to a12345 + 2. -define i8* @fold_memchr_a12345_3_9() { +define ptr @fold_memchr_a12345_3_9() { ; CHECK-LABEL: @fold_memchr_a12345_3_9( -; CHECK-NEXT: ret i8* getelementptr inbounds ([5 x i8], [5 x i8]* @a12345, i64 0, i64 2) +; CHECK-NEXT: ret ptr getelementptr inbounds ([5 x i8], ptr @a12345, i64 0, i64 2) ; - %ptr = getelementptr [5 x i8], [5 x i8]* @a12345, i32 0, i32 0 - %res = call i8* @memchr(i8* %ptr, i32 3, i64 9) - ret i8* %res + %res = call ptr @memchr(ptr @a12345, i32 3, i64 9) + ret ptr %res } ; Fold memchr(a123f45, 500, 9) to a123f45 + 3 (verify that 500 is ; truncated to (unsigned char)500 == '\xf4') -define i8* @fold_memchr_a123f45_500_9() { +define ptr @fold_memchr_a123f45_500_9() { ; CHECK-LABEL: @fold_memchr_a123f45_500_9( -; CHECK-NEXT: ret i8* getelementptr inbounds ([5 x i8], [5 x i8]* @a123f45, i64 0, i64 3) +; CHECK-NEXT: ret ptr getelementptr inbounds ([5 x i8], ptr @a123f45, i64 0, i64 3) ; - %ptr = getelementptr [5 x i8], [5 x i8]* @a123f45, i32 0, i32 0 - %res = call i8* @memchr(i8* %ptr, i32 500, i64 9) - ret i8* %res + %res = call ptr @memchr(ptr @a123f45, i32 500, i64 9) + ret ptr %res } ; Fold memchr(a12345, '\03', n) to n < 3 ? null : a12345 + 2. -define i8* @fold_a12345_3_n(i64 %n) { +define ptr @fold_a12345_3_n(i64 %n) { ; CHECK-LABEL: @fold_a12345_3_n( ; CHECK-NEXT: [[MEMCHR_CMP:%.*]] = icmp ult i64 [[N:%.*]], 3 -; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[MEMCHR_CMP]], i8* null, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @a12345, i64 0, i64 2) -; CHECK-NEXT: ret i8* [[TMP1]] +; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[MEMCHR_CMP]], ptr null, ptr getelementptr inbounds ([5 x i8], ptr @a12345, i64 0, i64 2) +; CHECK-NEXT: ret ptr [[TMP1]] ; - %ptr = getelementptr [5 x i8], [5 x i8]* @a12345, i32 0, i32 0 - %res = call i8* @memchr(i8* %ptr, i32 3, i64 %n) - ret i8* %res + %res = call ptr @memchr(ptr @a12345, i32 3, i64 %n) + ret ptr %res } ; Fold memchr(a12345, 259, n) to n < 3 ? null : a12345 + 2 ; to verify the constant 259 is converted to unsigned char (yielding 3). -define i8* @fold_a12345_259_n(i64 %n) { +define ptr @fold_a12345_259_n(i64 %n) { ; CHECK-LABEL: @fold_a12345_259_n( ; CHECK-NEXT: [[MEMCHR_CMP:%.*]] = icmp ult i64 [[N:%.*]], 3 -; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[MEMCHR_CMP]], i8* null, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @a12345, i64 0, i64 2) -; CHECK-NEXT: ret i8* [[TMP1]] +; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[MEMCHR_CMP]], ptr null, ptr getelementptr inbounds ([5 x i8], ptr @a12345, i64 0, i64 2) +; CHECK-NEXT: ret ptr [[TMP1]] ; - %ptr = getelementptr [5 x i8], [5 x i8]* @a12345, i32 0, i32 0 - %res = call i8* @memchr(i8* %ptr, i32 259, i64 %n) - ret i8* %res + %res = call ptr @memchr(ptr @a12345, i32 259, i64 %n) + ret ptr %res } ; Do no fold memchr(ax, 1, n). -define i8* @call_ax_1_n(i64 %n) { +define ptr @call_ax_1_n(i64 %n) { ; CHECK-LABEL: @call_ax_1_n( -; CHECK-NEXT: [[RES:%.*]] = call i8* @memchr(i8* getelementptr inbounds ([0 x i8], [0 x i8]* @ax, i64 0, i64 0), i32 1, i64 [[N:%.*]]) -; CHECK-NEXT: ret i8* [[RES]] +; CHECK-NEXT: [[RES:%.*]] = call ptr @memchr(ptr nonnull @ax, i32 1, i64 [[N:%.*]]) +; CHECK-NEXT: ret ptr [[RES]] ; - %ptr = getelementptr [0 x i8], [0 x i8]* @ax, i32 0, i32 0 - %res = call i8* @memchr(i8* %ptr, i32 1, i64 %n) - ret i8* %res + %res = call ptr @memchr(ptr @ax, i32 1, i64 %n) + ret ptr %res } diff --git a/llvm/test/Transforms/InstCombine/memchr-4.ll b/llvm/test/Transforms/InstCombine/memchr-4.ll --- a/llvm/test/Transforms/InstCombine/memchr-4.ll +++ b/llvm/test/Transforms/InstCombine/memchr-4.ll @@ -5,7 +5,7 @@ ; value that results in the call being incorrectly folded (as might happen ; when LLVM is compiled in ILP32 mode). -declare i8* @memchr(i8*, i32, i64) +declare ptr @memchr(ptr, i32, i64) @ax = external global [0 x i8] @a12345 = constant [5 x i8] c"\01\02\03\04\05" @@ -14,56 +14,52 @@ ; Do not fold memchr(ax, 1, UINT_MAX + (size_t)1) to null. Only the first ; byte in ax must be dereferenceable. -define i8* @call_memchr_ax_2_uimax_p1() { +define ptr @call_memchr_ax_2_uimax_p1() { ; CHECK-LABEL: @call_memchr_ax_2_uimax_p1( -; CHECK-NEXT: [[RES:%.*]] = call i8* @memchr(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([0 x i8], [0 x i8]* @ax, i64 0, i64 0), i32 1, i64 4294967296) -; CHECK-NEXT: ret i8* [[RES]] +; CHECK-NEXT: [[RES:%.*]] = call ptr @memchr(ptr noundef nonnull @ax, i32 1, i64 4294967296) +; CHECK-NEXT: ret ptr [[RES]] ; - %ptr = getelementptr [0 x i8], [0 x i8]* @ax, i32 0, i32 0 - %res = call i8* @memchr(i8* %ptr, i32 1, i64 4294967296) - ret i8* %res + %res = call ptr @memchr(ptr @ax, i32 1, i64 4294967296) + ret ptr %res } ; Do not fold memchr(ax, 1, UINT_MAX + (size_t)2) to *ax == 1 ? ax : null. ; As above, only the first byte in ax must be dereferenceable. -define i8* @call_memchr_ax_2_uimax_p2() { +define ptr @call_memchr_ax_2_uimax_p2() { ; CHECK-LABEL: @call_memchr_ax_2_uimax_p2( -; CHECK-NEXT: [[RES:%.*]] = call i8* @memchr(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([0 x i8], [0 x i8]* @ax, i64 0, i64 0), i32 1, i64 4294967296) -; CHECK-NEXT: ret i8* [[RES]] +; CHECK-NEXT: [[RES:%.*]] = call ptr @memchr(ptr noundef nonnull @ax, i32 1, i64 4294967296) +; CHECK-NEXT: ret ptr [[RES]] ; - %ptr = getelementptr [0 x i8], [0 x i8]* @ax, i32 0, i32 0 - %res = call i8* @memchr(i8* %ptr, i32 1, i64 4294967296) - ret i8* %res + %res = call ptr @memchr(ptr @ax, i32 1, i64 4294967296) + ret ptr %res } ; Fold memchr(a12345, 3, UINT_MAX + (size_t)2) to a12345 + 2 (and not to ; null). -define i8* @fold_memchr_a12345_3_uimax_p2() { +define ptr @fold_memchr_a12345_3_uimax_p2() { ; CHECK-LABEL: @fold_memchr_a12345_3_uimax_p2( -; CHECK-NEXT: ret i8* getelementptr inbounds ([5 x i8], [5 x i8]* @a12345, i64 0, i64 2) +; CHECK-NEXT: ret ptr getelementptr inbounds ([5 x i8], ptr @a12345, i64 0, i64 2) ; - %ptr = getelementptr [5 x i8], [5 x i8]* @a12345, i32 0, i32 0 - %res = call i8* @memchr(i8* %ptr, i32 3, i64 4294967297) - ret i8* %res + %res = call ptr @memchr(ptr @a12345, i32 3, i64 4294967297) + ret ptr %res } ; Do not fold memchr(a12345, c, UINT_MAX + (size_t)2). -define i8* @fold_memchr_a12345_c_uimax_p2(i32 %0) { +define ptr @fold_memchr_a12345_c_uimax_p2(i32 %0) { ; CHECK-LABEL: @fold_memchr_a12345_c_uimax_p2( -; CHECK-NEXT: [[RES:%.*]] = call i8* @memchr(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x i8], [5 x i8]* @a12345, i64 0, i64 0), i32 [[TMP0:%.*]], i64 4294967297) -; CHECK-NEXT: ret i8* [[RES]] +; CHECK-NEXT: [[RES:%.*]] = call ptr @memchr(ptr noundef nonnull @a12345, i32 [[TMP0:%.*]], i64 4294967297) +; CHECK-NEXT: ret ptr [[RES]] ; - %ptr = getelementptr [5 x i8], [5 x i8]* @a12345, i32 0, i32 0 - %res = call i8* @memchr(i8* %ptr, i32 %0, i64 4294967297) - ret i8* %res + %res = call ptr @memchr(ptr @a12345, i32 %0, i64 4294967297) + ret ptr %res } diff --git a/llvm/test/Transforms/InstCombine/memchr-6.ll b/llvm/test/Transforms/InstCombine/memchr-6.ll --- a/llvm/test/Transforms/InstCombine/memchr-6.ll +++ b/llvm/test/Transforms/InstCombine/memchr-6.ll @@ -4,7 +4,7 @@ ; Verify that memchr calls with a string consisting of all the same ; characters are folded and those with mixed strings are not. -declare i8* @memchr(i8*, i32, i64) +declare ptr @memchr(ptr, i32, i64) @a00000 = constant [5 x i8] zeroinitializer @a11111 = constant [5 x i8] c"\01\01\01\01\01" @@ -16,133 +16,125 @@ ; TODO: This depends on getConstantStringInfo() being able to handle ; implicitly zeroed out constants. -define i8* @fold_memchr_a00000_c_5(i32 %C) { +define ptr @fold_memchr_a00000_c_5(i32 %C) { ; CHECK-LABEL: @fold_memchr_a00000_c_5( -; CHECK-NEXT: [[RET:%.*]] = call i8* @memchr(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x i8], [5 x i8]* @a00000, i64 0, i64 0), i32 [[C:%.*]], i64 5) -; CHECK-NEXT: ret i8* [[RET]] +; CHECK-NEXT: [[RET:%.*]] = call ptr @memchr(ptr noundef nonnull @a00000, i32 [[C:%.*]], i64 5) +; CHECK-NEXT: ret ptr [[RET]] ; - %ptr = getelementptr [5 x i8], [5 x i8]* @a00000, i64 0, i64 0 - %ret = call i8* @memchr(i8* %ptr, i32 %C, i64 5) - ret i8* %ret + %ret = call ptr @memchr(ptr @a00000, i32 %C, i64 5) + ret ptr %ret } ; Fold memchr(a11111, C, 5) to *a11111 == C ? a11111 : null. -define i8* @fold_memchr_a11111_c_5(i32 %C) { +define ptr @fold_memchr_a11111_c_5(i32 %C) { ; CHECK-LABEL: @fold_memchr_a11111_c_5( ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[C:%.*]] to i8 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 1 -; CHECK-NEXT: [[MEMCHR_SEL2:%.*]] = select i1 [[TMP2]], i8* getelementptr inbounds ([5 x i8], [5 x i8]* @a11111, i64 0, i64 0), i8* null -; CHECK-NEXT: ret i8* [[MEMCHR_SEL2]] +; CHECK-NEXT: [[MEMCHR_SEL2:%.*]] = select i1 [[TMP2]], ptr @a11111, ptr null +; CHECK-NEXT: ret ptr [[MEMCHR_SEL2]] ; - %ptr = getelementptr [5 x i8], [5 x i8]* @a11111, i64 0, i64 0 - %ret = call i8* @memchr(i8* %ptr, i32 %C, i64 5) - ret i8* %ret + %ret = call ptr @memchr(ptr @a11111, i32 %C, i64 5) + ret ptr %ret } ; Fold memchr(a11111, C, N) to N && *a11111 == C ? a11111 : null, ; on the assumption that N is in bounds. -define i8* @fold_memchr_a11111_c_n(i32 %C, i64 %N) { +define ptr @fold_memchr_a11111_c_n(i32 %C, i64 %N) { ; CHECK-LABEL: @fold_memchr_a11111_c_n( ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[C:%.*]] to i8 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 1 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i64 [[N:%.*]], 0 ; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP3]], [[TMP2]] -; CHECK-NEXT: [[MEMCHR_SEL2:%.*]] = select i1 [[TMP4]], i8* getelementptr inbounds ([5 x i8], [5 x i8]* @a11111, i64 0, i64 0), i8* null -; CHECK-NEXT: ret i8* [[MEMCHR_SEL2]] +; CHECK-NEXT: [[MEMCHR_SEL2:%.*]] = select i1 [[TMP4]], ptr @a11111, ptr null +; CHECK-NEXT: ret ptr [[MEMCHR_SEL2]] ; - %ptr = getelementptr [5 x i8], [5 x i8]* @a11111, i64 0, i64 0 - %ret = call i8* @memchr(i8* %ptr, i32 %C, i64 %N) - ret i8* %ret + %ret = call ptr @memchr(ptr @a11111, i32 %C, i64 %N) + ret ptr %ret } ; Fold memchr(a111122, C, N) to ; N != 0 && C == 1 ? a111122 : N > 4 && C == 2 ? a111122 + 4 : null. -define i8* @fold_memchr_a111122_c_n(i32 %C, i64 %N) { +define ptr @fold_memchr_a111122_c_n(i32 %C, i64 %N) { ; CHECK-LABEL: @fold_memchr_a111122_c_n( ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[C:%.*]] to i8 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 2 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ugt i64 [[N:%.*]], 4 ; CHECK-NEXT: [[TMP4:%.*]] = and i1 [[TMP2]], [[TMP3]] -; CHECK-NEXT: [[MEMCHR_SEL1:%.*]] = select i1 [[TMP4]], i8* getelementptr inbounds ([6 x i8], [6 x i8]* @a111122, i64 0, i64 4), i8* null +; CHECK-NEXT: [[MEMCHR_SEL1:%.*]] = select i1 [[TMP4]], ptr getelementptr inbounds ([6 x i8], ptr @a111122, i64 0, i64 4), ptr null ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i8 [[TMP1]], 1 ; CHECK-NEXT: [[TMP6:%.*]] = icmp ne i64 [[N]], 0 ; CHECK-NEXT: [[TMP7:%.*]] = and i1 [[TMP6]], [[TMP5]] -; CHECK-NEXT: [[MEMCHR_SEL2:%.*]] = select i1 [[TMP7]], i8* getelementptr inbounds ([6 x i8], [6 x i8]* @a111122, i64 0, i64 0), i8* [[MEMCHR_SEL1]] -; CHECK-NEXT: ret i8* [[MEMCHR_SEL2]] +; CHECK-NEXT: [[MEMCHR_SEL2:%.*]] = select i1 [[TMP7]], ptr @a111122, ptr [[MEMCHR_SEL1]] +; CHECK-NEXT: ret ptr [[MEMCHR_SEL2]] ; - %ptr = getelementptr [6 x i8], [6 x i8]* @a111122, i64 0, i64 0 - %ret = call i8* @memchr(i8* %ptr, i32 %C, i64 %N) - ret i8* %ret + %ret = call ptr @memchr(ptr @a111122, i32 %C, i64 %N) + ret ptr %ret } ; Fold memchr(a1110111, C, 3) to a1110111[2] == C ? a1110111 : null. -define i8* @fold_memchr_a1110111_c_3(i32 %C) { +define ptr @fold_memchr_a1110111_c_3(i32 %C) { ; CHECK-LABEL: @fold_memchr_a1110111_c_3( ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[C:%.*]] to i8 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 1 -; CHECK-NEXT: [[MEMCHR_SEL2:%.*]] = select i1 [[TMP2]], i8* getelementptr inbounds ([7 x i8], [7 x i8]* @a1110111, i64 0, i64 0), i8* null -; CHECK-NEXT: ret i8* [[MEMCHR_SEL2]] +; CHECK-NEXT: [[MEMCHR_SEL2:%.*]] = select i1 [[TMP2]], ptr @a1110111, ptr null +; CHECK-NEXT: ret ptr [[MEMCHR_SEL2]] ; - %ptr = getelementptr [7 x i8], [7 x i8]* @a1110111, i64 0, i64 0 - %ret = call i8* @memchr(i8* %ptr, i32 %C, i64 3) - ret i8* %ret + %ret = call ptr @memchr(ptr @a1110111, i32 %C, i64 3) + ret ptr %ret } ; Don't fold memchr(a1110111, C, 4). -define i8* @call_memchr_a1110111_c_4(i32 %C) { +define ptr @call_memchr_a1110111_c_4(i32 %C) { ; CHECK-LABEL: @call_memchr_a1110111_c_4( ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[C:%.*]] to i8 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 0 -; CHECK-NEXT: [[MEMCHR_SEL1:%.*]] = select i1 [[TMP2]], i8* getelementptr inbounds ([7 x i8], [7 x i8]* @a1110111, i64 0, i64 3), i8* null +; CHECK-NEXT: [[MEMCHR_SEL1:%.*]] = select i1 [[TMP2]], ptr getelementptr inbounds ([7 x i8], ptr @a1110111, i64 0, i64 3), ptr null ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP1]], 1 -; CHECK-NEXT: [[MEMCHR_SEL2:%.*]] = select i1 [[TMP3]], i8* getelementptr inbounds ([7 x i8], [7 x i8]* @a1110111, i64 0, i64 0), i8* [[MEMCHR_SEL1]] -; CHECK-NEXT: ret i8* [[MEMCHR_SEL2]] +; CHECK-NEXT: [[MEMCHR_SEL2:%.*]] = select i1 [[TMP3]], ptr @a1110111, ptr [[MEMCHR_SEL1]] +; CHECK-NEXT: ret ptr [[MEMCHR_SEL2]] ; - %ptr = getelementptr [7 x i8], [7 x i8]* @a1110111, i64 0, i64 0 - %ret = call i8* @memchr(i8* %ptr, i32 %C, i64 4) - ret i8* %ret + %ret = call ptr @memchr(ptr @a1110111, i32 %C, i64 4) + ret ptr %ret } ; Don't fold memchr(a1110111, C, 7). -define i8* @call_memchr_a1110111_c_7(i32 %C) { +define ptr @call_memchr_a1110111_c_7(i32 %C) { ; CHECK-LABEL: @call_memchr_a1110111_c_7( -; CHECK-NEXT: [[RET:%.*]] = call i8* @memchr(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([7 x i8], [7 x i8]* @a1110111, i64 0, i64 0), i32 [[C:%.*]], i64 7) -; CHECK-NEXT: ret i8* [[RET]] +; CHECK-NEXT: [[RET:%.*]] = call ptr @memchr(ptr noundef nonnull @a1110111, i32 [[C:%.*]], i64 7) +; CHECK-NEXT: ret ptr [[RET]] ; - %ptr = getelementptr [7 x i8], [7 x i8]* @a1110111, i64 0, i64 0 - %ret = call i8* @memchr(i8* %ptr, i32 %C, i64 7) - ret i8* %ret + %ret = call ptr @memchr(ptr @a1110111, i32 %C, i64 7) + ret ptr %ret } ; Don't fold memchr(a1110111, C, N). -define i8* @call_memchr_a1110111_c_n(i32 %C, i64 %N) { +define ptr @call_memchr_a1110111_c_n(i32 %C, i64 %N) { ; CHECK-LABEL: @call_memchr_a1110111_c_n( -; CHECK-NEXT: [[RET:%.*]] = call i8* @memchr(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @a1110111, i64 0, i64 0), i32 [[C:%.*]], i64 [[N:%.*]]) -; CHECK-NEXT: ret i8* [[RET]] +; CHECK-NEXT: [[RET:%.*]] = call ptr @memchr(ptr nonnull @a1110111, i32 [[C:%.*]], i64 [[N:%.*]]) +; CHECK-NEXT: ret ptr [[RET]] ; - %ptr = getelementptr [7 x i8], [7 x i8]* @a1110111, i64 0, i64 0 - %ret = call i8* @memchr(i8* %ptr, i32 %C, i64 %N) - ret i8* %ret + %ret = call ptr @memchr(ptr @a1110111, i32 %C, i64 %N) + ret ptr %ret } diff --git a/llvm/test/Transforms/InstCombine/memchr-7.ll b/llvm/test/Transforms/InstCombine/memchr-7.ll --- a/llvm/test/Transforms/InstCombine/memchr-7.ll +++ b/llvm/test/Transforms/InstCombine/memchr-7.ll @@ -4,17 +4,17 @@ @.str = private unnamed_addr constant [27 x i8] c"abcdefghijklmnopqrstuvwxyz\00", align 1 @.str.1 = private unnamed_addr constant [2 x i8] c"\0D\0A", align 1 -declare i8* @strchr(i8*, i32) -declare i8* @memchr(i8*, i32, i64) +declare ptr @strchr(ptr, i32) +declare ptr @memchr(ptr, i32, i64) define zeroext i1 @strchr_to_memchr_n_equals_len(i32 %c) { ; CHECK-LABEL: @strchr_to_memchr_n_equals_len( -; CHECK-NEXT: [[MEMCHR:%.*]] = tail call i8* @memchr(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([27 x i8], [27 x i8]* @.str, i64 0, i64 0), i32 [[C:%.*]], i64 27) -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8* [[MEMCHR]], null +; CHECK-NEXT: [[MEMCHR:%.*]] = tail call ptr @memchr(ptr noundef nonnull @.str, i32 [[C:%.*]], i64 27) +; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr [[MEMCHR]], null ; CHECK-NEXT: ret i1 [[CMP]] ; - %call = tail call i8* @strchr(i8* nonnull dereferenceable(27) getelementptr inbounds ([27 x i8], [27 x i8]* @.str, i64 0, i64 0), i32 %c) - %cmp = icmp ne i8* %call, null + %call = tail call ptr @strchr(ptr nonnull dereferenceable(27) @.str, i32 %c) + %cmp = icmp ne ptr %call, null ret i1 %cmp } @@ -26,68 +26,68 @@ ; CHECK-NEXT: [[CMP:%.*]] = and i1 [[TMP3]], [[TMP2]] ; CHECK-NEXT: ret i1 [[CMP]] ; - %call = tail call i8* @memchr(i8* nonnull dereferenceable(3) getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0), i32 %c, i64 2) - %cmp = icmp eq i8* %call, null + %call = tail call ptr @memchr(ptr nonnull dereferenceable(3) @.str.1, i32 %c, i64 2) + %cmp = icmp eq ptr %call, null ret i1 %cmp } define zeroext i1 @memchr_n_less_than_len(i32 %c) { ; CHECK-LABEL: @memchr_n_less_than_len( -; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @memchr(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([27 x i8], [27 x i8]* @.str, i64 0, i64 0), i32 [[C:%.*]], i64 15) -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8* [[CALL]], null +; CHECK-NEXT: [[CALL:%.*]] = tail call ptr @memchr(ptr noundef nonnull @.str, i32 [[C:%.*]], i64 15) +; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr [[CALL]], null ; CHECK-NEXT: ret i1 [[CMP]] ; - %call = tail call i8* @memchr(i8* getelementptr inbounds ([27 x i8], [27 x i8]* @.str, i64 0, i64 0), i32 %c, i64 15) - %cmp = icmp ne i8* %call, null + %call = tail call ptr @memchr(ptr @.str, i32 %c, i64 15) + %cmp = icmp ne ptr %call, null ret i1 %cmp } define zeroext i1 @memchr_n_more_than_len(i32 %c) { ; CHECK-LABEL: @memchr_n_more_than_len( -; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @memchr(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([27 x i8], [27 x i8]* @.str, i64 0, i64 0), i32 [[C:%.*]], i64 30) -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8* [[CALL]], null +; CHECK-NEXT: [[CALL:%.*]] = tail call ptr @memchr(ptr noundef nonnull @.str, i32 [[C:%.*]], i64 30) +; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr [[CALL]], null ; CHECK-NEXT: ret i1 [[CMP]] ; - %call = tail call i8* @memchr(i8* getelementptr inbounds ([27 x i8], [27 x i8]* @.str, i64 0, i64 0), i32 %c, i64 30) - %cmp = icmp ne i8* %call, null + %call = tail call ptr @memchr(ptr @.str, i32 %c, i64 30) + %cmp = icmp ne ptr %call, null ret i1 %cmp } ; Negative test - no comparison with zero -define i8* @memchr_no_zero_cmp(i32 %c) { +define ptr @memchr_no_zero_cmp(i32 %c) { ; CHECK-LABEL: @memchr_no_zero_cmp( -; CHECK-NEXT: [[MEMCHR:%.*]] = tail call i8* @memchr(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([27 x i8], [27 x i8]* @.str, i64 0, i64 0), i32 [[C:%.*]], i64 27) -; CHECK-NEXT: ret i8* [[MEMCHR]] +; CHECK-NEXT: [[MEMCHR:%.*]] = tail call ptr @memchr(ptr noundef nonnull @.str, i32 [[C:%.*]], i64 27) +; CHECK-NEXT: ret ptr [[MEMCHR]] ; - %call = tail call i8* @strchr(i8* nonnull dereferenceable(27) getelementptr inbounds ([27 x i8], [27 x i8]* @.str, i64 0, i64 0), i32 %c) - ret i8* %call + %call = tail call ptr @strchr(ptr nonnull dereferenceable(27) @.str, i32 %c) + ret ptr %call } -define i8* @memchr_no_zero_cmp2(i32 %c) { +define ptr @memchr_no_zero_cmp2(i32 %c) { ; CHECK-LABEL: @memchr_no_zero_cmp2( ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[C:%.*]] to i8 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 10 -; CHECK-NEXT: [[MEMCHR_SEL1:%.*]] = select i1 [[TMP2]], i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 1), i8* null +; CHECK-NEXT: [[MEMCHR_SEL1:%.*]] = select i1 [[TMP2]], ptr getelementptr inbounds ([2 x i8], ptr @.str.1, i64 0, i64 1), ptr null ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP1]], 13 -; CHECK-NEXT: [[MEMCHR_SEL2:%.*]] = select i1 [[TMP3]], i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0), i8* [[MEMCHR_SEL1]] -; CHECK-NEXT: ret i8* [[MEMCHR_SEL2]] +; CHECK-NEXT: [[MEMCHR_SEL2:%.*]] = select i1 [[TMP3]], ptr @.str.1, ptr [[MEMCHR_SEL1]] +; CHECK-NEXT: ret ptr [[MEMCHR_SEL2]] ; - %call = tail call i8* @strchr(i8* nonnull dereferenceable(3) getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0), i32 %c) - ret i8* %call + %call = tail call ptr @strchr(ptr nonnull dereferenceable(3) @.str.1, i32 %c) + ret ptr %call } ; Negative test - opt for size define zeroext i1 @memchr_n_equals_len_minsize(i32 %c) minsize { ; CHECK-LABEL: @memchr_n_equals_len_minsize( -; CHECK-NEXT: [[MEMCHR:%.*]] = tail call i8* @memchr(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([27 x i8], [27 x i8]* @.str, i64 0, i64 0), i32 [[C:%.*]], i64 27) -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8* [[MEMCHR]], null +; CHECK-NEXT: [[MEMCHR:%.*]] = tail call ptr @memchr(ptr noundef nonnull @.str, i32 [[C:%.*]], i64 27) +; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr [[MEMCHR]], null ; CHECK-NEXT: ret i1 [[CMP]] ; - %call = tail call i8* @strchr(i8* nonnull dereferenceable(27) getelementptr inbounds ([27 x i8], [27 x i8]* @.str, i64 0, i64 0), i32 %c) - %cmp = icmp ne i8* %call, null + %call = tail call ptr @strchr(ptr nonnull dereferenceable(27) @.str, i32 %c) + %cmp = icmp ne ptr %call, null ret i1 %cmp } @@ -99,7 +99,7 @@ ; CHECK-NEXT: [[CMP:%.*]] = and i1 [[TMP3]], [[TMP2]] ; CHECK-NEXT: ret i1 [[CMP]] ; - %call = tail call i8* @memchr(i8* nonnull dereferenceable(3) getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0), i32 %c, i64 2) - %cmp = icmp eq i8* %call, null + %call = tail call ptr @memchr(ptr nonnull dereferenceable(3) @.str.1, i32 %c, i64 2) + %cmp = icmp eq ptr %call, null ret i1 %cmp } diff --git a/llvm/test/Transforms/InstCombine/memchr-9.ll b/llvm/test/Transforms/InstCombine/memchr-9.ll --- a/llvm/test/Transforms/InstCombine/memchr-9.ll +++ b/llvm/test/Transforms/InstCombine/memchr-9.ll @@ -8,7 +8,7 @@ ; pointers into constant arrays of types larger than char and fractional ; offsets. -declare i8* @memchr(i8*, i32, i64) +declare ptr @memchr(ptr, i32, i64) %struct.A = type { [2 x i16], [2 x i16] } @@ -16,219 +16,211 @@ @a = constant [1 x %struct.A] [%struct.A { [2 x i16] [i16 0, i16 257], [2 x i16] [i16 514, i16 771] }] -define void @fold_memchr_A_pIb_cst_cst(i8** %pchr) { +define void @fold_memchr_A_pIb_cst_cst(ptr %pchr) { ; CHECK-LABEL: @fold_memchr_A_pIb_cst_cst( -; CHECK-NEXT: store i8* bitcast ([1 x %struct.A]* @a to i8*), i8** [[PCHR:%.*]], align 8 -; CHECK-NEXT: [[PST_0_1_1:%.*]] = getelementptr i8*, i8** [[PCHR]], i64 1 -; CHECK-NEXT: store i8* null, i8** [[PST_0_1_1]], align 8 -; CHECK-NEXT: [[PST_0_4_4:%.*]] = getelementptr i8*, i8** [[PCHR]], i64 2 -; CHECK-NEXT: store i8* null, i8** [[PST_0_4_4]], align 8 -; CHECK-NEXT: [[PST_1_0_1:%.*]] = getelementptr i8*, i8** [[PCHR]], i64 3 -; CHECK-NEXT: store i8* getelementptr (i8, i8* bitcast ([1 x %struct.A]* @a to i8*), i64 1), i8** [[PST_1_0_1]], align 8 -; CHECK-NEXT: [[PST_1_0_3:%.*]] = getelementptr i8*, i8** [[PCHR]], i64 4 -; CHECK-NEXT: store i8* getelementptr (i8, i8* bitcast ([1 x %struct.A]* @a to i8*), i64 1), i8** [[PST_1_0_3]], align 8 -; CHECK-NEXT: [[PST_1_1_1:%.*]] = getelementptr i8*, i8** [[PCHR]], i64 5 -; CHECK-NEXT: store i8* null, i8** [[PST_1_1_1]], align 8 -; CHECK-NEXT: [[PST_1_1_2:%.*]] = getelementptr i8*, i8** [[PCHR]], i64 6 -; CHECK-NEXT: store i8* bitcast (i16* getelementptr inbounds ([1 x %struct.A], [1 x %struct.A]* @a, i64 0, i64 0, i32 0, i64 1) to i8*), i8** [[PST_1_1_2]], align 8 -; CHECK-NEXT: [[PST_1_3_3:%.*]] = getelementptr i8*, i8** [[PCHR]], i64 7 -; CHECK-NEXT: store i8* null, i8** [[PST_1_3_3]], align 8 -; CHECK-NEXT: [[PST_1_3_4:%.*]] = getelementptr i8*, i8** [[PCHR]], i64 8 -; CHECK-NEXT: store i8* null, i8** [[PST_1_3_4]], align 8 -; CHECK-NEXT: [[PST_1_3_6:%.*]] = getelementptr i8*, i8** [[PCHR]], i64 10 -; CHECK-NEXT: store i8* bitcast (i16* getelementptr inbounds ([1 x %struct.A], [1 x %struct.A]* @a, i64 0, i64 0, i32 1, i64 1) to i8*), i8** [[PST_1_3_6]], align 8 +; CHECK-NEXT: store ptr @a, ptr [[PCHR:%.*]], align 8 +; CHECK-NEXT: [[PST_0_1_1:%.*]] = getelementptr ptr, ptr [[PCHR]], i64 1 +; CHECK-NEXT: store ptr null, ptr [[PST_0_1_1]], align 8 +; CHECK-NEXT: [[PST_0_4_4:%.*]] = getelementptr ptr, ptr [[PCHR]], i64 2 +; CHECK-NEXT: store ptr null, ptr [[PST_0_4_4]], align 8 +; CHECK-NEXT: [[PST_1_0_1:%.*]] = getelementptr ptr, ptr [[PCHR]], i64 3 +; CHECK-NEXT: store ptr getelementptr inbounds (i8, ptr @a, i64 1), ptr [[PST_1_0_1]], align 8 +; CHECK-NEXT: [[PST_1_0_3:%.*]] = getelementptr ptr, ptr [[PCHR]], i64 4 +; CHECK-NEXT: store ptr getelementptr inbounds (i8, ptr @a, i64 1), ptr [[PST_1_0_3]], align 8 +; CHECK-NEXT: [[PST_1_1_1:%.*]] = getelementptr ptr, ptr [[PCHR]], i64 5 +; CHECK-NEXT: store ptr null, ptr [[PST_1_1_1]], align 8 +; CHECK-NEXT: [[PST_1_1_2:%.*]] = getelementptr ptr, ptr [[PCHR]], i64 6 +; CHECK-NEXT: store ptr getelementptr inbounds ([1 x %struct.A], ptr @a, i64 0, i64 0, i32 0, i64 1), ptr [[PST_1_1_2]], align 8 +; CHECK-NEXT: [[PST_1_3_3:%.*]] = getelementptr ptr, ptr [[PCHR]], i64 7 +; CHECK-NEXT: store ptr null, ptr [[PST_1_3_3]], align 8 +; CHECK-NEXT: [[PST_1_3_4:%.*]] = getelementptr ptr, ptr [[PCHR]], i64 8 +; CHECK-NEXT: store ptr null, ptr [[PST_1_3_4]], align 8 +; CHECK-NEXT: [[PST_1_3_6:%.*]] = getelementptr ptr, ptr [[PCHR]], i64 10 +; CHECK-NEXT: store ptr getelementptr inbounds ([1 x %struct.A], ptr @a, i64 0, i64 0, i32 1, i64 1), ptr [[PST_1_3_6]], align 8 ; CHECK-NEXT: ret void ; - %pa = getelementptr [1 x %struct.A], [1 x %struct.A]* @a, i64 0, i64 0 - %pi8a = bitcast %struct.A* %pa to i8* - %pi8ap0 = getelementptr i8, i8* %pi8a, i32 0 ; Fold memchr((char*)a + 0, '\0', 1) to a. - %pst_0_0_1 = getelementptr i8*, i8** %pchr, i32 0 - %chr_0_0_1 = call i8* @memchr(i8* %pi8ap0, i32 0, i64 1) - store i8* %chr_0_0_1, i8** %pst_0_0_1 + %chr_0_0_1 = call ptr @memchr(ptr @a, i32 0, i64 1) + store ptr %chr_0_0_1, ptr %pchr ; Fold memchr((char*)a + 0, '\01', 1) to null. - %pst_0_1_1 = getelementptr i8*, i8** %pchr, i32 1 - %chr_0_1_1 = call i8* @memchr(i8* %pi8ap0, i32 1, i64 1) - store i8* %chr_0_1_1, i8** %pst_0_1_1 + %pst_0_1_1 = getelementptr ptr, ptr %pchr, i32 1 + %chr_0_1_1 = call ptr @memchr(ptr @a, i32 1, i64 1) + store ptr %chr_0_1_1, ptr %pst_0_1_1 ; Fold memchr((char*)a + 0, '\04', 4) to null. - %pst_0_4_4 = getelementptr i8*, i8** %pchr, i32 2 - %chr_0_4_4 = call i8* @memchr(i8* %pi8ap0, i32 4, i64 4) - store i8* %chr_0_4_4, i8** %pst_0_4_4 + %pst_0_4_4 = getelementptr ptr, ptr %pchr, i32 2 + %chr_0_4_4 = call ptr @memchr(ptr @a, i32 4, i64 4) + store ptr %chr_0_4_4, ptr %pst_0_4_4 - %pi8ap1 = getelementptr i8, i8* %pi8a, i32 1 + %pi8ap1 = getelementptr i8, ptr @a, i32 1 ; Fold memchr((char*)a + 1, '\0', 1) to (char*)a + 1. - %pst_1_0_1 = getelementptr i8*, i8** %pchr, i32 3 - %chr_1_0_1 = call i8* @memchr(i8* %pi8ap1, i32 0, i64 1) - store i8* %chr_1_0_1, i8** %pst_1_0_1 + %pst_1_0_1 = getelementptr ptr, ptr %pchr, i32 3 + %chr_1_0_1 = call ptr @memchr(ptr %pi8ap1, i32 0, i64 1) + store ptr %chr_1_0_1, ptr %pst_1_0_1 ; Fold memchr((char*)a + 1, '\0', 3) to (char*)a + 1. - %pst_1_0_3 = getelementptr i8*, i8** %pchr, i32 4 - %chr_1_0_3 = call i8* @memchr(i8* %pi8ap1, i32 0, i64 3) - store i8* %chr_1_0_3, i8** %pst_1_0_3 + %pst_1_0_3 = getelementptr ptr, ptr %pchr, i32 4 + %chr_1_0_3 = call ptr @memchr(ptr %pi8ap1, i32 0, i64 3) + store ptr %chr_1_0_3, ptr %pst_1_0_3 ; Fold memchr((char*)a + 1, '\01', 1) to null. - %pst_1_1_1 = getelementptr i8*, i8** %pchr, i32 5 - %chr_1_1_1 = call i8* @memchr(i8* %pi8ap1, i32 1, i64 1) - store i8* %chr_1_1_1, i8** %pst_1_1_1 + %pst_1_1_1 = getelementptr ptr, ptr %pchr, i32 5 + %chr_1_1_1 = call ptr @memchr(ptr %pi8ap1, i32 1, i64 1) + store ptr %chr_1_1_1, ptr %pst_1_1_1 ; Fold memchr((char*)a + 1, '\01', 2) to (char*)a + 2. - %pst_1_1_2 = getelementptr i8*, i8** %pchr, i32 6 - %chr_1_1_2 = call i8* @memchr(i8* %pi8ap1, i32 1, i64 2) - store i8* %chr_1_1_2, i8** %pst_1_1_2 + %pst_1_1_2 = getelementptr ptr, ptr %pchr, i32 6 + %chr_1_1_2 = call ptr @memchr(ptr %pi8ap1, i32 1, i64 2) + store ptr %chr_1_1_2, ptr %pst_1_1_2 ; Fold memchr((char*)a + 1, '\03', 3) to null. - %pst_1_3_3 = getelementptr i8*, i8** %pchr, i32 7 - %chr_1_3_3 = call i8* @memchr(i8* %pi8ap1, i32 3, i64 3) - store i8* %chr_1_3_3, i8** %pst_1_3_3 + %pst_1_3_3 = getelementptr ptr, ptr %pchr, i32 7 + %chr_1_3_3 = call ptr @memchr(ptr %pi8ap1, i32 3, i64 3) + store ptr %chr_1_3_3, ptr %pst_1_3_3 ; Fold memchr((char*)a + 1, '\03', 4) to null. - %pst_1_3_4 = getelementptr i8*, i8** %pchr, i32 8 - %chr_1_3_4 = call i8* @memchr(i8* %pi8ap1, i32 3, i64 4) - store i8* %chr_1_3_4, i8** %pst_1_3_4 + %pst_1_3_4 = getelementptr ptr, ptr %pchr, i32 8 + %chr_1_3_4 = call ptr @memchr(ptr %pi8ap1, i32 3, i64 4) + store ptr %chr_1_3_4, ptr %pst_1_3_4 ; Fold memchr((char*)a + 1, '\03', 5) to null. - %pst_1_3_5 = getelementptr i8*, i8** %pchr, i32 9 - %chr_1_3_5 = call i8* @memchr(i8* %pi8ap1, i32 3, i64 5) - store i8* %chr_1_3_4, i8** %pst_1_3_4 + %pst_1_3_5 = getelementptr ptr, ptr %pchr, i32 9 + %chr_1_3_5 = call ptr @memchr(ptr %pi8ap1, i32 3, i64 5) + store ptr %chr_1_3_4, ptr %pst_1_3_4 ; Fold memchr((char*)a + 1, '\03', 6) to (char*)a + 5. - %pst_1_3_6 = getelementptr i8*, i8** %pchr, i32 10 - %chr_1_3_6 = call i8* @memchr(i8* %pi8ap1, i32 3, i64 6) - store i8* %chr_1_3_6, i8** %pst_1_3_6 + %pst_1_3_6 = getelementptr ptr, ptr %pchr, i32 10 + %chr_1_3_6 = call ptr @memchr(ptr %pi8ap1, i32 3, i64 6) + store ptr %chr_1_3_6, ptr %pst_1_3_6 ret void } -define void @fold_memchr_A_pIb_cst_N(i64 %N, i8** %pchr) { +define void @fold_memchr_A_pIb_cst_N(i64 %N, ptr %pchr) { ; CHECK-LABEL: @fold_memchr_A_pIb_cst_N( ; CHECK-NEXT: [[MEMCHR_CMP:%.*]] = icmp eq i64 [[N:%.*]], 0 -; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[MEMCHR_CMP]], i8* null, i8* bitcast ([1 x %struct.A]* @a to i8*) -; CHECK-NEXT: store i8* [[TMP1]], i8** [[PCHR:%.*]], align 8 -; CHECK-NEXT: [[PST_0_1_N:%.*]] = getelementptr i8*, i8** [[PCHR]], i64 1 +; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[MEMCHR_CMP]], ptr null, ptr @a +; CHECK-NEXT: store ptr [[TMP1]], ptr [[PCHR:%.*]], align 8 +; CHECK-NEXT: [[PST_0_1_N:%.*]] = getelementptr ptr, ptr [[PCHR]], i64 1 ; CHECK-NEXT: [[MEMCHR_CMP1:%.*]] = icmp ult i64 [[N]], 3 -; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[MEMCHR_CMP1]], i8* null, i8* bitcast (i16* getelementptr inbounds ([1 x %struct.A], [1 x %struct.A]* @a, i64 0, i64 0, i32 0, i64 1) to i8*) -; CHECK-NEXT: store i8* [[TMP2]], i8** [[PST_0_1_N]], align 8 -; CHECK-NEXT: [[PST_0_4_N:%.*]] = getelementptr i8*, i8** [[PCHR]], i64 2 -; CHECK-NEXT: store i8* null, i8** [[PST_0_4_N]], align 8 -; CHECK-NEXT: [[PST_1_0_N:%.*]] = getelementptr i8*, i8** [[PCHR]], i64 3 +; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[MEMCHR_CMP1]], ptr null, ptr getelementptr inbounds ([1 x %struct.A], ptr @a, i64 0, i64 0, i32 0, i64 1) +; CHECK-NEXT: store ptr [[TMP2]], ptr [[PST_0_1_N]], align 8 +; CHECK-NEXT: [[PST_0_4_N:%.*]] = getelementptr ptr, ptr [[PCHR]], i64 2 +; CHECK-NEXT: store ptr null, ptr [[PST_0_4_N]], align 8 +; CHECK-NEXT: [[PST_1_0_N:%.*]] = getelementptr ptr, ptr [[PCHR]], i64 3 ; CHECK-NEXT: [[MEMCHR_CMP2:%.*]] = icmp eq i64 [[N]], 0 -; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[MEMCHR_CMP2]], i8* null, i8* getelementptr (i8, i8* bitcast ([1 x %struct.A]* @a to i8*), i64 1) -; CHECK-NEXT: store i8* [[TMP3]], i8** [[PST_1_0_N]], align 8 -; CHECK-NEXT: [[PST_1_1_N:%.*]] = getelementptr i8*, i8** [[PCHR]], i64 4 +; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[MEMCHR_CMP2]], ptr null, ptr getelementptr inbounds (i8, ptr @a, i64 1) +; CHECK-NEXT: store ptr [[TMP3]], ptr [[PST_1_0_N]], align 8 +; CHECK-NEXT: [[PST_1_1_N:%.*]] = getelementptr ptr, ptr [[PCHR]], i64 4 ; CHECK-NEXT: [[MEMCHR_CMP3:%.*]] = icmp ult i64 [[N]], 2 -; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[MEMCHR_CMP3]], i8* null, i8* bitcast (i16* getelementptr inbounds ([1 x %struct.A], [1 x %struct.A]* @a, i64 0, i64 0, i32 0, i64 1) to i8*) -; CHECK-NEXT: store i8* [[TMP4]], i8** [[PST_1_1_N]], align 8 -; CHECK-NEXT: [[PST_1_2_N:%.*]] = getelementptr i8*, i8** [[PCHR]], i64 5 +; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[MEMCHR_CMP3]], ptr null, ptr getelementptr inbounds ([1 x %struct.A], ptr @a, i64 0, i64 0, i32 0, i64 1) +; CHECK-NEXT: store ptr [[TMP4]], ptr [[PST_1_1_N]], align 8 +; CHECK-NEXT: [[PST_1_2_N:%.*]] = getelementptr ptr, ptr [[PCHR]], i64 5 ; CHECK-NEXT: [[MEMCHR_CMP4:%.*]] = icmp ult i64 [[N]], 4 -; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[MEMCHR_CMP4]], i8* null, i8* bitcast (i16* getelementptr inbounds ([1 x %struct.A], [1 x %struct.A]* @a, i64 0, i64 0, i32 1, i64 0) to i8*) -; CHECK-NEXT: store i8* [[TMP5]], i8** [[PST_1_2_N]], align 8 -; CHECK-NEXT: [[PST_1_3_N:%.*]] = getelementptr i8*, i8** [[PCHR]], i64 6 +; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[MEMCHR_CMP4]], ptr null, ptr getelementptr inbounds ([1 x %struct.A], ptr @a, i64 0, i64 0, i32 1, i64 0) +; CHECK-NEXT: store ptr [[TMP5]], ptr [[PST_1_2_N]], align 8 +; CHECK-NEXT: [[PST_1_3_N:%.*]] = getelementptr ptr, ptr [[PCHR]], i64 6 ; CHECK-NEXT: [[MEMCHR_CMP5:%.*]] = icmp ult i64 [[N]], 6 -; CHECK-NEXT: [[TMP6:%.*]] = select i1 [[MEMCHR_CMP5]], i8* null, i8* bitcast (i16* getelementptr inbounds ([1 x %struct.A], [1 x %struct.A]* @a, i64 0, i64 0, i32 1, i64 1) to i8*) -; CHECK-NEXT: store i8* [[TMP6]], i8** [[PST_1_3_N]], align 8 -; CHECK-NEXT: [[PST_1_4_N:%.*]] = getelementptr i8*, i8** [[PCHR]], i64 7 -; CHECK-NEXT: store i8* null, i8** [[PST_1_4_N]], align 8 -; CHECK-NEXT: [[PST_2_0_N:%.*]] = getelementptr i8*, i8** [[PCHR]], i64 8 -; CHECK-NEXT: store i8* null, i8** [[PST_2_0_N]], align 8 -; CHECK-NEXT: [[PST_2_1_N:%.*]] = getelementptr i8*, i8** [[PCHR]], i64 9 +; CHECK-NEXT: [[TMP6:%.*]] = select i1 [[MEMCHR_CMP5]], ptr null, ptr getelementptr inbounds ([1 x %struct.A], ptr @a, i64 0, i64 0, i32 1, i64 1) +; CHECK-NEXT: store ptr [[TMP6]], ptr [[PST_1_3_N]], align 8 +; CHECK-NEXT: [[PST_1_4_N:%.*]] = getelementptr ptr, ptr [[PCHR]], i64 7 +; CHECK-NEXT: store ptr null, ptr [[PST_1_4_N]], align 8 +; CHECK-NEXT: [[PST_2_0_N:%.*]] = getelementptr ptr, ptr [[PCHR]], i64 8 +; CHECK-NEXT: store ptr null, ptr [[PST_2_0_N]], align 8 +; CHECK-NEXT: [[PST_2_1_N:%.*]] = getelementptr ptr, ptr [[PCHR]], i64 9 ; CHECK-NEXT: [[MEMCHR_CMP6:%.*]] = icmp eq i64 [[N]], 0 -; CHECK-NEXT: [[TMP7:%.*]] = select i1 [[MEMCHR_CMP6]], i8* null, i8* bitcast (i16* getelementptr inbounds ([1 x %struct.A], [1 x %struct.A]* @a, i64 0, i64 0, i32 0, i64 1) to i8*) -; CHECK-NEXT: store i8* [[TMP7]], i8** [[PST_2_1_N]], align 8 -; CHECK-NEXT: [[PST_2_2_N:%.*]] = getelementptr i8*, i8** [[PCHR]], i64 10 +; CHECK-NEXT: [[TMP7:%.*]] = select i1 [[MEMCHR_CMP6]], ptr null, ptr getelementptr inbounds ([1 x %struct.A], ptr @a, i64 0, i64 0, i32 0, i64 1) +; CHECK-NEXT: store ptr [[TMP7]], ptr [[PST_2_1_N]], align 8 +; CHECK-NEXT: [[PST_2_2_N:%.*]] = getelementptr ptr, ptr [[PCHR]], i64 10 ; CHECK-NEXT: [[MEMCHR_CMP7:%.*]] = icmp ult i64 [[N]], 3 -; CHECK-NEXT: [[TMP8:%.*]] = select i1 [[MEMCHR_CMP7]], i8* null, i8* bitcast (i16* getelementptr inbounds ([1 x %struct.A], [1 x %struct.A]* @a, i64 0, i64 0, i32 1, i64 0) to i8*) -; CHECK-NEXT: store i8* [[TMP8]], i8** [[PST_2_2_N]], align 8 -; CHECK-NEXT: [[PST_2_3_N:%.*]] = getelementptr i8*, i8** [[PCHR]], i64 11 +; CHECK-NEXT: [[TMP8:%.*]] = select i1 [[MEMCHR_CMP7]], ptr null, ptr getelementptr inbounds ([1 x %struct.A], ptr @a, i64 0, i64 0, i32 1, i64 0) +; CHECK-NEXT: store ptr [[TMP8]], ptr [[PST_2_2_N]], align 8 +; CHECK-NEXT: [[PST_2_3_N:%.*]] = getelementptr ptr, ptr [[PCHR]], i64 11 ; CHECK-NEXT: [[MEMCHR_CMP8:%.*]] = icmp ult i64 [[N]], 5 -; CHECK-NEXT: [[TMP9:%.*]] = select i1 [[MEMCHR_CMP8]], i8* null, i8* bitcast (i16* getelementptr inbounds ([1 x %struct.A], [1 x %struct.A]* @a, i64 0, i64 0, i32 1, i64 1) to i8*) -; CHECK-NEXT: store i8* [[TMP9]], i8** [[PST_2_3_N]], align 8 -; CHECK-NEXT: [[PST_2_4_N:%.*]] = getelementptr i8*, i8** [[PCHR]], i64 12 -; CHECK-NEXT: store i8* null, i8** [[PST_2_4_N]], align 8 +; CHECK-NEXT: [[TMP9:%.*]] = select i1 [[MEMCHR_CMP8]], ptr null, ptr getelementptr inbounds ([1 x %struct.A], ptr @a, i64 0, i64 0, i32 1, i64 1) +; CHECK-NEXT: store ptr [[TMP9]], ptr [[PST_2_3_N]], align 8 +; CHECK-NEXT: [[PST_2_4_N:%.*]] = getelementptr ptr, ptr [[PCHR]], i64 12 +; CHECK-NEXT: store ptr null, ptr [[PST_2_4_N]], align 8 ; CHECK-NEXT: ret void ; - %pa = getelementptr [1 x %struct.A], [1 x %struct.A]* @a, i64 0, i64 0 - %pi8a = bitcast %struct.A* %pa to i8* - %pi8ap0 = getelementptr i8, i8* %pi8a, i32 0 ; Fold memchr((char*)a + 0, '\0', N) to N ? a : null. - %pst_0_0_n = getelementptr i8*, i8** %pchr, i32 0 - %chr_0_0_n = call i8* @memchr(i8* %pi8ap0, i32 0, i64 %N) - store i8* %chr_0_0_n, i8** %pst_0_0_n + %chr_0_0_n = call ptr @memchr(ptr @a, i32 0, i64 %N) + store ptr %chr_0_0_n, ptr %pchr ; Fold memchr((char*)a + 0, '\01', N) to N < 2 ? null : a. - %pst_0_1_n = getelementptr i8*, i8** %pchr, i32 1 - %chr_0_1_n = call i8* @memchr(i8* %pi8ap0, i32 1, i64 %N) - store i8* %chr_0_1_n, i8** %pst_0_1_n + %pst_0_1_n = getelementptr ptr, ptr %pchr, i32 1 + %chr_0_1_n = call ptr @memchr(ptr @a, i32 1, i64 %N) + store ptr %chr_0_1_n, ptr %pst_0_1_n ; Fold memchr((char*)a + 0, '\04', N) to null. - %pst_0_4_n = getelementptr i8*, i8** %pchr, i32 2 - %chr_0_4_n = call i8* @memchr(i8* %pi8ap0, i32 4, i64 %N) - store i8* %chr_0_4_n, i8** %pst_0_4_n + %pst_0_4_n = getelementptr ptr, ptr %pchr, i32 2 + %chr_0_4_n = call ptr @memchr(ptr @a, i32 4, i64 %N) + store ptr %chr_0_4_n, ptr %pst_0_4_n - %pi8ap1 = getelementptr i8, i8* %pi8a, i32 1 + %pi8ap1 = getelementptr i8, ptr @a, i32 1 ; Fold memchr((char*)a + 1, '\0', N) to null. - %pst_1_0_n = getelementptr i8*, i8** %pchr, i32 3 - %chr_1_0_n = call i8* @memchr(i8* %pi8ap1, i32 0, i64 %N) - store i8* %chr_1_0_n, i8** %pst_1_0_n + %pst_1_0_n = getelementptr ptr, ptr %pchr, i32 3 + %chr_1_0_n = call ptr @memchr(ptr %pi8ap1, i32 0, i64 %N) + store ptr %chr_1_0_n, ptr %pst_1_0_n ; Fold memchr((char*)a + 1, '\01', N) N ? (char*)a + 1 : null. - %pst_1_1_n = getelementptr i8*, i8** %pchr, i32 4 - %chr_1_1_n = call i8* @memchr(i8* %pi8ap1, i32 1, i64 %N) - store i8* %chr_1_1_n, i8** %pst_1_1_n + %pst_1_1_n = getelementptr ptr, ptr %pchr, i32 4 + %chr_1_1_n = call ptr @memchr(ptr %pi8ap1, i32 1, i64 %N) + store ptr %chr_1_1_n, ptr %pst_1_1_n ; Fold memchr((char*)a + 1, '\02', N) to N < 2 ? null : (char*)a + 4. - %pst_1_2_n = getelementptr i8*, i8** %pchr, i32 5 - %chr_1_2_n = call i8* @memchr(i8* %pi8ap1, i32 2, i64 %N) - store i8* %chr_1_2_n, i8** %pst_1_2_n + %pst_1_2_n = getelementptr ptr, ptr %pchr, i32 5 + %chr_1_2_n = call ptr @memchr(ptr %pi8ap1, i32 2, i64 %N) + store ptr %chr_1_2_n, ptr %pst_1_2_n ; Fold memchr((char*)a + 1, '\03', N) to N < 6 ? null : (char*)a + 6. - %pst_1_3_n = getelementptr i8*, i8** %pchr, i32 6 - %chr_1_3_n = call i8* @memchr(i8* %pi8ap1, i32 3, i64 %N) - store i8* %chr_1_3_n, i8** %pst_1_3_n + %pst_1_3_n = getelementptr ptr, ptr %pchr, i32 6 + %chr_1_3_n = call ptr @memchr(ptr %pi8ap1, i32 3, i64 %N) + store ptr %chr_1_3_n, ptr %pst_1_3_n ; Fold memchr((char*)a + 1, '\04', N) to null. - %pst_1_4_n = getelementptr i8*, i8** %pchr, i32 7 - %chr_1_4_n = call i8* @memchr(i8* %pi8ap1, i32 4, i64 %N) - store i8* %chr_1_4_n, i8** %pst_1_4_n + %pst_1_4_n = getelementptr ptr, ptr %pchr, i32 7 + %chr_1_4_n = call ptr @memchr(ptr %pi8ap1, i32 4, i64 %N) + store ptr %chr_1_4_n, ptr %pst_1_4_n - %pi8ap2 = getelementptr i8, i8* %pi8a, i32 2 + %pi8ap2 = getelementptr i8, ptr @a, i32 2 ; Fold memchr((char*)a + 2, '\0', N) to null. - %pst_2_0_n = getelementptr i8*, i8** %pchr, i32 8 - %chr_2_0_n = call i8* @memchr(i8* %pi8ap2, i32 0, i64 %N) - store i8* %chr_2_0_n, i8** %pst_2_0_n + %pst_2_0_n = getelementptr ptr, ptr %pchr, i32 8 + %chr_2_0_n = call ptr @memchr(ptr %pi8ap2, i32 0, i64 %N) + store ptr %chr_2_0_n, ptr %pst_2_0_n ; Fold memchr((char*)a + 2, '\01', N) N ? (char*)a + 2 : null. - %pst_2_1_n = getelementptr i8*, i8** %pchr, i32 9 - %chr_2_1_n = call i8* @memchr(i8* %pi8ap2, i32 1, i64 %N) - store i8* %chr_2_1_n, i8** %pst_2_1_n + %pst_2_1_n = getelementptr ptr, ptr %pchr, i32 9 + %chr_2_1_n = call ptr @memchr(ptr %pi8ap2, i32 1, i64 %N) + store ptr %chr_2_1_n, ptr %pst_2_1_n ; Fold memchr((char*)a + 2, '\02', N) to N < 3 ? null : (char*)a + 2. - %pst_2_2_n = getelementptr i8*, i8** %pchr, i32 10 - %chr_2_2_n = call i8* @memchr(i8* %pi8ap2, i32 2, i64 %N) - store i8* %chr_2_2_n, i8** %pst_2_2_n + %pst_2_2_n = getelementptr ptr, ptr %pchr, i32 10 + %chr_2_2_n = call ptr @memchr(ptr %pi8ap2, i32 2, i64 %N) + store ptr %chr_2_2_n, ptr %pst_2_2_n ; Fold memchr((char*)a + 2, '\03', N) to N < 5 ? null : (char*)a + 4. - %pst_2_3_n = getelementptr i8*, i8** %pchr, i32 11 - %chr_2_3_n = call i8* @memchr(i8* %pi8ap2, i32 3, i64 %N) - store i8* %chr_2_3_n, i8** %pst_2_3_n + %pst_2_3_n = getelementptr ptr, ptr %pchr, i32 11 + %chr_2_3_n = call ptr @memchr(ptr %pi8ap2, i32 3, i64 %N) + store ptr %chr_2_3_n, ptr %pst_2_3_n ; Fold memchr((char*)a + 2, '\04', N) to null. - %pst_2_4_n = getelementptr i8*, i8** %pchr, i32 12 - %chr_2_4_n = call i8* @memchr(i8* %pi8ap2, i32 4, i64 %N) - store i8* %chr_2_4_n, i8** %pst_2_4_n + %pst_2_4_n = getelementptr ptr, ptr %pchr, i32 12 + %chr_2_4_n = call ptr @memchr(ptr %pi8ap2, i32 4, i64 %N) + store ptr %chr_2_4_n, ptr %pst_2_4_n ret void } @@ -236,47 +228,42 @@ ; Verify that calls with out of bounds offsets are not folded. -define void @call_memchr_A_pIb_xs_cst(i8** %pchr) { +define void @call_memchr_A_pIb_xs_cst(ptr %pchr) { ; CHECK-LABEL: @call_memchr_A_pIb_xs_cst( -; CHECK-NEXT: [[CHR_1_0_0_2:%.*]] = call i8* @memchr(i8* noundef nonnull dereferenceable(1) bitcast (%struct.A* getelementptr inbounds ([1 x %struct.A], [1 x %struct.A]* @a, i64 1, i64 0) to i8*), i32 0, i64 2) -; CHECK-NEXT: store i8* [[CHR_1_0_0_2]], i8** [[PCHR:%.*]], align 8 -; CHECK-NEXT: [[PST_1_0_1_2:%.*]] = getelementptr i8*, i8** [[PCHR]], i64 1 -; CHECK-NEXT: [[CHR_1_0_1_2:%.*]] = call i8* @memchr(i8* noundef nonnull dereferenceable(1) bitcast (%struct.A* getelementptr inbounds ([1 x %struct.A], [1 x %struct.A]* @a, i64 1, i64 0) to i8*), i32 0, i64 2) -; CHECK-NEXT: store i8* [[CHR_1_0_1_2]], i8** [[PST_1_0_1_2]], align 8 -; CHECK-NEXT: [[PST_0_0_8_2:%.*]] = getelementptr i8*, i8** [[PCHR]], i64 2 -; CHECK-NEXT: [[CHR_0_0_8_2:%.*]] = call i8* @memchr(i8* noundef nonnull dereferenceable(1) bitcast (i16* getelementptr inbounds ([1 x %struct.A], [1 x %struct.A]* @a, i64 1, i64 0, i32 0, i64 0) to i8*), i32 0, i64 2) -; CHECK-NEXT: store i8* [[CHR_0_0_8_2]], i8** [[PST_0_0_8_2]], align 8 +; CHECK-NEXT: [[CHR_1_0_0_2:%.*]] = call ptr @memchr(ptr noundef nonnull dereferenceable(1) getelementptr inbounds ([1 x %struct.A], ptr @a, i64 1, i64 0), i32 0, i64 2) +; CHECK-NEXT: store ptr [[CHR_1_0_0_2]], ptr [[PCHR:%.*]], align 8 +; CHECK-NEXT: [[PST_1_0_1_2:%.*]] = getelementptr ptr, ptr [[PCHR]], i64 1 +; CHECK-NEXT: [[CHR_1_0_1_2:%.*]] = call ptr @memchr(ptr noundef nonnull dereferenceable(1) getelementptr inbounds ([1 x %struct.A], ptr @a, i64 1, i64 0), i32 0, i64 2) +; CHECK-NEXT: store ptr [[CHR_1_0_1_2]], ptr [[PST_1_0_1_2]], align 8 +; CHECK-NEXT: [[PST_0_0_8_2:%.*]] = getelementptr ptr, ptr [[PCHR]], i64 2 +; CHECK-NEXT: [[CHR_0_0_8_2:%.*]] = call ptr @memchr(ptr noundef nonnull dereferenceable(1) getelementptr inbounds ([1 x %struct.A], ptr @a, i64 1, i64 0, i32 0, i64 0), i32 0, i64 2) +; CHECK-NEXT: store ptr [[CHR_0_0_8_2]], ptr [[PST_0_0_8_2]], align 8 ; CHECK-NEXT: ret void ; ; Verify that the call isn't folded when the first GEP index is excessive. - %pa1 = getelementptr [1 x %struct.A], [1 x %struct.A]* @a, i64 1, i64 0 - %pi8a1 = bitcast %struct.A* %pa1 to i8* + %pa1 = getelementptr [1 x %struct.A], ptr @a, i64 1, i64 0 - %pi8a1p0 = getelementptr i8, i8* %pi8a1, i32 0 ; Don't fold memchr((char*)&a[1] + 0, '\0', 2). - %pst_1_0_0_2 = getelementptr i8*, i8** %pchr, i32 0 - %chr_1_0_0_2 = call i8* @memchr(i8* %pi8a1p0, i32 0, i64 2) - store i8* %chr_1_0_0_2, i8** %pst_1_0_0_2 + %chr_1_0_0_2 = call ptr @memchr(ptr %pa1, i32 0, i64 2) + store ptr %chr_1_0_0_2, ptr %pchr - %pi8a1p1 = getelementptr i8, i8* %pi8a1, i32 1 + %pi8a1p1 = getelementptr i8, ptr %pa1, i32 1 ; Likewise, don't fold memchr((char*)&a[1] + 1, '\0', 2). - %pst_1_0_1_2 = getelementptr i8*, i8** %pchr, i32 1 - %chr_1_0_1_2 = call i8* @memchr(i8* %pi8a1p0, i32 0, i64 2) - store i8* %chr_1_0_1_2, i8** %pst_1_0_1_2 + %pst_1_0_1_2 = getelementptr ptr, ptr %pchr, i32 1 + %chr_1_0_1_2 = call ptr @memchr(ptr %pa1, i32 0, i64 2) + store ptr %chr_1_0_1_2, ptr %pst_1_0_1_2 ; Verify that the call isn't folded when the first GEP index is in bounds ; but the byte offset is excessive. - %pa0 = getelementptr [1 x %struct.A], [1 x %struct.A]* @a, i64 0, i64 0 - %pi8a0 = bitcast %struct.A* %pa0 to i8* - %pi8a0p8 = getelementptr i8, i8* %pi8a0, i32 8 + %pi8a0p8 = getelementptr i8, ptr @a, i32 8 ; Don't fold memchr((char*)&a[0] + 8, '\0', 2). - %pst_0_0_8_2 = getelementptr i8*, i8** %pchr, i32 2 - %chr_0_0_8_2 = call i8* @memchr(i8* %pi8a0p8, i32 0, i64 2) - store i8* %chr_0_0_8_2, i8** %pst_0_0_8_2 + %pst_0_0_8_2 = getelementptr ptr, ptr %pchr, i32 2 + %chr_0_0_8_2 = call ptr @memchr(ptr %pi8a0p8, i32 0, i64 2) + store ptr %chr_0_0_8_2, ptr %pst_0_0_8_2 ret void } @@ -287,21 +274,18 @@ ; Verify that a memchr call with an argument consisting of three GEPs ; is folded. -define i8* @fold_memchr_gep_gep_gep() { +define ptr @fold_memchr_gep_gep_gep() { ; CHECK-LABEL: @fold_memchr_gep_gep_gep( -; CHECK-NEXT: ret i8* bitcast (i16* getelementptr (i16, i16* bitcast (i32* getelementptr (i32, i32* bitcast (i64* getelementptr inbounds ([2 x i64], [2 x i64]* @ai64, i64 0, i64 1) to i32*), i64 1) to i16*), i64 1) to i8*) +; CHECK-NEXT: ret ptr getelementptr (i16, ptr getelementptr (i32, ptr getelementptr inbounds ([2 x i64], ptr @ai64, i64 0, i64 1), i64 1), i64 1) ; - %p8_1 = getelementptr [2 x i64], [2 x i64]* @ai64, i64 0, i64 1 - %p4_0 = bitcast i64* %p8_1 to i32* - %p4_1 = getelementptr i32, i32* %p4_0, i64 1 + %p8_1 = getelementptr [2 x i64], ptr @ai64, i64 0, i64 1 + %p4_1 = getelementptr i32, ptr %p8_1, i64 1 - %p2_0 = bitcast i32* %p4_1 to i16* - %p2_1 = getelementptr i16, i16* %p2_0, i64 1 - %q2_1 = bitcast i16* %p2_1 to i8* + %p2_1 = getelementptr i16, ptr %p4_1, i64 1 - %pc = call i8* @memchr(i8* %q2_1, i32 -1, i64 2) - ret i8* %pc + %pc = call ptr @memchr(ptr %p2_1, i32 -1, i64 2) + ret ptr %pc } @@ -311,14 +295,14 @@ ; Verify memchr folding of a union member. -define i8* @fold_memchr_union_member() { -; CHECK-LABEL: @fold_memchr_union_member( -; BE-CHECK-NEXT: ret i8* getelementptr (i8, i8* bitcast (%union.U* @u to i8*), i64 5) -; LE-CHECK-NEXT: ret i8* bitcast (i32* getelementptr inbounds (%union.U, %union.U* @u, i64 0, i32 0, i64 1) to i8*) +define ptr @fold_memchr_union_member() { +; BE-CHECK-LABEL: @fold_memchr_union_member( +; BE-CHECK-NEXT: ret ptr getelementptr inbounds (i8, ptr @u, i64 5) ; - %pu = getelementptr %union.U, %union.U* @u, i64 0 - %pi8u = bitcast %union.U* %pu to i8* - %pi8u_p1 = getelementptr i8, i8* %pi8u, i64 1 - %pc = call i8* @memchr(i8* %pi8u_p1, i32 34, i64 8) - ret i8* %pc +; LE-CHECK-LABEL: @fold_memchr_union_member( +; LE-CHECK-NEXT: ret ptr getelementptr inbounds ([[UNION_U:%.*]], ptr @u, i64 0, i32 0, i64 1) +; + %pi8u_p1 = getelementptr i8, ptr @u, i64 1 + %pc = call ptr @memchr(ptr %pi8u_p1, i32 34, i64 8) + ret ptr %pc } diff --git a/llvm/test/Transforms/InstCombine/memchr.ll b/llvm/test/Transforms/InstCombine/memchr.ll --- a/llvm/test/Transforms/InstCombine/memchr.ll +++ b/llvm/test/Transforms/InstCombine/memchr.ll @@ -11,120 +11,111 @@ @single = constant [2 x i8] c"\1F\00" @spaces = constant [4 x i8] c" \0D\0A\00" @negative = constant [3 x i8] c"\FF\FE\00" -@chp = global i8* zeroinitializer +@chp = global ptr zeroinitializer -declare i8* @memchr(i8*, i32, i32) +declare ptr @memchr(ptr, i32, i32) define void @test1() { ; CHECK-LABEL: @test1( -; CHECK-NEXT: store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 6), i8** @chp, align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([14 x i8], ptr @hello, i32 0, i32 6), ptr @chp, align 4 ; CHECK-NEXT: ret void ; - %str = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0 - %dst = call i8* @memchr(i8* %str, i32 119, i32 14) - store i8* %dst, i8** @chp + %dst = call ptr @memchr(ptr @hello, i32 119, i32 14) + store ptr %dst, ptr @chp ret void } define void @test2() { ; CHECK-LABEL: @test2( -; CHECK-NEXT: store i8* null, i8** @chp, align 4 +; CHECK-NEXT: store ptr null, ptr @chp, align 4 ; CHECK-NEXT: ret void ; - %str = getelementptr [1 x i8], [1 x i8]* @null, i32 0, i32 0 - %dst = call i8* @memchr(i8* %str, i32 119, i32 1) - store i8* %dst, i8** @chp + %dst = call ptr @memchr(ptr @null, i32 119, i32 1) + store ptr %dst, ptr @chp ret void } define void @test3() { ; CHECK-LABEL: @test3( -; CHECK-NEXT: store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 13), i8** @chp, align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([14 x i8], ptr @hello, i32 0, i32 13), ptr @chp, align 4 ; CHECK-NEXT: ret void ; - %src = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0 - %dst = call i8* @memchr(i8* %src, i32 0, i32 14) - store i8* %dst, i8** @chp + %dst = call ptr @memchr(ptr @hello, i32 0, i32 14) + store ptr %dst, ptr @chp ret void } define void @test4(i32 %chr) { ; CHECK-LABEL: @test4( -; CHECK-NEXT: [[DST:%.*]] = call i8* @memchr(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 0), i32 [[CHR:%.*]], i32 14) -; CHECK-NEXT: store i8* [[DST]], i8** @chp, align 4 +; CHECK-NEXT: [[DST:%.*]] = call ptr @memchr(ptr noundef nonnull @hello, i32 [[CHR:%.*]], i32 14) +; CHECK-NEXT: store ptr [[DST]], ptr @chp, align 4 ; CHECK-NEXT: ret void ; - %src = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0 - %dst = call i8* @memchr(i8* %src, i32 %chr, i32 14) - store i8* %dst, i8** @chp + %dst = call ptr @memchr(ptr @hello, i32 %chr, i32 14) + store ptr %dst, ptr @chp ret void } define void @test5() { ; CHECK-LABEL: @test5( -; CHECK-NEXT: store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 13), i8** @chp, align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([14 x i8], ptr @hello, i32 0, i32 13), ptr @chp, align 4 ; CHECK-NEXT: ret void ; - %src = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0 - %dst = call i8* @memchr(i8* %src, i32 65280, i32 14) - store i8* %dst, i8** @chp + %dst = call ptr @memchr(ptr @hello, i32 65280, i32 14) + store ptr %dst, ptr @chp ret void } define void @test6() { ; CHECK-LABEL: @test6( -; CHECK-NEXT: store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 6), i8** @chp, align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([14 x i8], ptr @hello, i32 0, i32 6), ptr @chp, align 4 ; CHECK-NEXT: ret void ; - %src = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0 ; Overflow, but we still find the right thing. - %dst = call i8* @memchr(i8* %src, i32 119, i32 100) - store i8* %dst, i8** @chp + %dst = call ptr @memchr(ptr @hello, i32 119, i32 100) + store ptr %dst, ptr @chp ret void } define void @test7() { ; CHECK-LABEL: @test7( -; CHECK-NEXT: store i8* null, i8** @chp, align 4 +; CHECK-NEXT: store ptr null, ptr @chp, align 4 ; CHECK-NEXT: ret void ; - %src = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0 ; Overflow - %dst = call i8* @memchr(i8* %src, i32 120, i32 100) - store i8* %dst, i8** @chp + %dst = call ptr @memchr(ptr @hello, i32 120, i32 100) + store ptr %dst, ptr @chp ret void } define void @test8() { ; CHECK-LABEL: @test8( -; CHECK-NEXT: store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hellonull, i32 0, i32 6), i8** @chp, align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([14 x i8], ptr @hellonull, i32 0, i32 6), ptr @chp, align 4 ; CHECK-NEXT: ret void ; - %str = getelementptr [14 x i8], [14 x i8]* @hellonull, i32 0, i32 0 - %dst = call i8* @memchr(i8* %str, i32 119, i32 14) - store i8* %dst, i8** @chp + %dst = call ptr @memchr(ptr @hellonull, i32 119, i32 14) + store ptr %dst, ptr @chp ret void } define void @test9() { ; CHECK-LABEL: @test9( -; CHECK-NEXT: store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hellonull, i32 0, i32 6), i8** @chp, align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([14 x i8], ptr @hellonull, i32 0, i32 6), ptr @chp, align 4 ; CHECK-NEXT: ret void ; - %str = getelementptr [14 x i8], [14 x i8]* @hellonull, i32 0, i32 2 - %dst = call i8* @memchr(i8* %str, i32 119, i32 12) - store i8* %dst, i8** @chp + %str = getelementptr [14 x i8], ptr @hellonull, i32 0, i32 2 + %dst = call ptr @memchr(ptr %str, i32 119, i32 12) + store ptr %dst, ptr @chp ret void } define void @test10() { ; CHECK-LABEL: @test10( -; CHECK-NEXT: store i8* null, i8** @chp, align 4 +; CHECK-NEXT: store ptr null, ptr @chp, align 4 ; CHECK-NEXT: ret void ; - %str = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0 - %dst = call i8* @memchr(i8* %str, i32 119, i32 6) - store i8* %dst, i8** @chp + %dst = call ptr @memchr(ptr @hello, i32 119, i32 6) + store ptr %dst, ptr @chp ret void } @@ -140,20 +131,20 @@ ; CHECK-NEXT: [[MEMCHR:%.*]] = select i1 [[MEMCHR_BOUNDS]], i1 [[MEMCHR_BITS]], i1 false ; CHECK-NEXT: ret i1 [[MEMCHR]] ; - %dst = call i8* @memchr(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @newlines, i64 0, i64 0), i32 %C, i32 3) - %cmp = icmp ne i8* %dst, null + %dst = call ptr @memchr(ptr @newlines, i32 %C, i32 3) + %cmp = icmp ne ptr %dst, null ret i1 %cmp } ; No 64 bits here define i1 @test12(i32 %C) { ; CHECK-LABEL: @test12( -; CHECK-NEXT: [[DST:%.*]] = call i8* @memchr(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([4 x i8], [4 x i8]* @spaces, i32 0, i32 0), i32 [[C:%.*]], i32 3) -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8* [[DST]], null +; CHECK-NEXT: [[DST:%.*]] = call ptr @memchr(ptr noundef nonnull @spaces, i32 [[C:%.*]], i32 3) +; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr [[DST]], null ; CHECK-NEXT: ret i1 [[CMP]] ; - %dst = call i8* @memchr(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @spaces, i64 0, i64 0), i32 %C, i32 3) - %cmp = icmp ne i8* %dst, null + %dst = call ptr @memchr(ptr @spaces, i32 %C, i32 3) + %cmp = icmp ne ptr %dst, null ret i1 %cmp } @@ -165,8 +156,8 @@ ; CHECK-NEXT: [[CMP:%.*]] = or i1 [[TMP3]], [[TMP2]] ; CHECK-NEXT: ret i1 [[CMP]] ; - %dst = call i8* @memchr(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @single, i64 0, i64 0), i32 %C, i32 2) - %cmp = icmp ne i8* %dst, null + %dst = call ptr @memchr(ptr @single, i32 %C, i32 2) + %cmp = icmp ne ptr %dst, null ret i1 %cmp } @@ -176,67 +167,67 @@ ; CHECK-NEXT: [[MEMCHR_CHAR0CMP:%.*]] = icmp eq i32 [[TMP1]], 31 ; CHECK-NEXT: ret i1 [[MEMCHR_CHAR0CMP]] ; - %dst = call i8* @memchr(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @single, i64 0, i64 0), i32 %C, i32 1) - %cmp = icmp ne i8* %dst, null + %dst = call ptr @memchr(ptr @single, i32 %C, i32 1) + %cmp = icmp ne ptr %dst, null ret i1 %cmp } define i1 @test15(i32 %C) { ; CHECK-LABEL: @test15( -; CHECK-NEXT: [[DST:%.*]] = call i8* @memchr(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([3 x i8], [3 x i8]* @negative, i32 0, i32 0), i32 [[C:%.*]], i32 3) -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8* [[DST]], null +; CHECK-NEXT: [[DST:%.*]] = call ptr @memchr(ptr noundef nonnull @negative, i32 [[C:%.*]], i32 3) +; CHECK-NEXT: [[CMP:%.*]] = icmp ne ptr [[DST]], null ; CHECK-NEXT: ret i1 [[CMP]] ; - %dst = call i8* @memchr(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @negative, i64 0, i64 0), i32 %C, i32 3) - %cmp = icmp ne i8* %dst, null + %dst = call ptr @memchr(ptr @negative, i32 %C, i32 3) + %cmp = icmp ne ptr %dst, null ret i1 %cmp } @s = internal constant [1 x i8] [i8 0], align 1 -define i8* @pr32124() { +define ptr @pr32124() { ; CHECK-LABEL: @pr32124( -; CHECK-NEXT: ret i8* getelementptr inbounds ([1 x i8], [1 x i8]* @s, i32 0, i32 0) +; CHECK-NEXT: ret ptr @s ; - %res = tail call i8* @memchr(i8* getelementptr ([1 x i8], [1 x i8]* @s, i64 0, i64 0), i32 0, i32 1) - ret i8* %res + %res = tail call ptr @memchr(ptr @s, i32 0, i32 1) + ret ptr %res } -define i8* @test16(i8* %str, i32 %c, i32 %n) { +define ptr @test16(ptr %str, i32 %c, i32 %n) { ; CHECK-LABEL: @test16( -; CHECK-NEXT: [[RET:%.*]] = call i8* @memchr(i8* [[STR:%.*]], i32 [[C:%.*]], i32 [[N:%.*]]) -; CHECK-NEXT: ret i8* [[RET]] +; CHECK-NEXT: [[RET:%.*]] = call ptr @memchr(ptr [[STR:%.*]], i32 [[C:%.*]], i32 [[N:%.*]]) +; CHECK-NEXT: ret ptr [[RET]] ; - %ret = call i8* @memchr(i8* %str, i32 %c, i32 %n) - ret i8* %ret + %ret = call ptr @memchr(ptr %str, i32 %c, i32 %n) + ret ptr %ret } -define i8* @test17(i8* %str, i32 %c, i32 %n) { +define ptr @test17(ptr %str, i32 %c, i32 %n) { ; CHECK-LABEL: @test17( -; CHECK-NEXT: [[RET:%.*]] = call i8* @memchr(i8* nonnull [[STR:%.*]], i32 [[C:%.*]], i32 [[N:%.*]]) -; CHECK-NEXT: ret i8* [[RET]] +; CHECK-NEXT: [[RET:%.*]] = call ptr @memchr(ptr nonnull [[STR:%.*]], i32 [[C:%.*]], i32 [[N:%.*]]) +; CHECK-NEXT: ret ptr [[RET]] ; - %ret = call i8* @memchr(i8* nonnull %str, i32 %c, i32 %n) - ret i8* %ret + %ret = call ptr @memchr(ptr nonnull %str, i32 %c, i32 %n) + ret ptr %ret } -define i8* @test18(i8* %str, i32 %c) { +define ptr @test18(ptr %str, i32 %c) { ; CHECK-LABEL: @test18( -; CHECK-NEXT: [[RET:%.*]] = call i8* @memchr(i8* noundef nonnull dereferenceable(1) [[STR:%.*]], i32 [[C:%.*]], i32 5) -; CHECK-NEXT: ret i8* [[RET]] +; CHECK-NEXT: [[RET:%.*]] = call ptr @memchr(ptr noundef nonnull dereferenceable(1) [[STR:%.*]], i32 [[C:%.*]], i32 5) +; CHECK-NEXT: ret ptr [[RET]] ; - %ret = call i8* @memchr(i8* %str, i32 %c, i32 5) - ret i8* %ret + %ret = call ptr @memchr(ptr %str, i32 %c, i32 5) + ret ptr %ret } -define i8* @test19(i8* %str, i32 %c) null_pointer_is_valid { +define ptr @test19(ptr %str, i32 %c) null_pointer_is_valid { ; CHECK-LABEL: @test19( -; CHECK-NEXT: [[RET:%.*]] = call i8* @memchr(i8* noundef [[STR:%.*]], i32 [[C:%.*]], i32 5) -; CHECK-NEXT: ret i8* [[RET]] +; CHECK-NEXT: [[RET:%.*]] = call ptr @memchr(ptr noundef [[STR:%.*]], i32 [[C:%.*]], i32 5) +; CHECK-NEXT: ret ptr [[RET]] ; - %ret = call i8* @memchr(i8* %str, i32 %c, i32 5) - ret i8* %ret + %ret = call ptr @memchr(ptr %str, i32 %c, i32 5) + ret ptr %ret } diff --git a/llvm/test/Transforms/InstCombine/memcpy_alloca.ll b/llvm/test/Transforms/InstCombine/memcpy_alloca.ll --- a/llvm/test/Transforms/InstCombine/memcpy_alloca.ll +++ b/llvm/test/Transforms/InstCombine/memcpy_alloca.ll @@ -2,84 +2,73 @@ ; RUN: opt < %s -passes=instcombine -S | FileCheck %s ; Memcpy is copying known-undef, and is thus removable -define void @test(i8* %dest) { +define void @test(ptr %dest) { ; CHECK-LABEL: @test( ; CHECK-NEXT: ret void ; %a = alloca [7 x i8] - %src = getelementptr inbounds [7 x i8], [7 x i8]* %a, i64 0, i64 0 - call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dest, i8* %src, i64 7, i1 false) + call void @llvm.memcpy.p0.p0.i64(ptr %dest, ptr %a, i64 7, i1 false) ret void } ; Some non-undef elements -define void @test2(i8* %dest) { +define void @test2(ptr %dest) { ; CHECK-LABEL: @test2( ; CHECK-NEXT: [[A:%.*]] = alloca [7 x i8], align 1 -; CHECK-NEXT: [[SRC:%.*]] = getelementptr inbounds [7 x i8], [7 x i8]* [[A]], i64 0, i64 0 -; CHECK-NEXT: store i8 0, i8* [[SRC]], align 1 -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(7) [[DEST:%.*]], i8* noundef nonnull align 1 dereferenceable(7) [[SRC]], i64 7, i1 false) +; CHECK-NEXT: store i8 0, ptr [[A]], align 1 +; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(7) [[DEST:%.*]], ptr noundef nonnull align 1 dereferenceable(7) [[A]], i64 7, i1 false) ; CHECK-NEXT: ret void ; %a = alloca [7 x i8] - %src = getelementptr inbounds [7 x i8], [7 x i8]* %a, i64 0, i64 0 - store i8 0, i8* %src - call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dest, i8* %src, i64 7, i1 false) + store i8 0, ptr %a + call void @llvm.memcpy.p0.p0.i64(ptr %dest, ptr %a, i64 7, i1 false) ret void } ; Volatile write is still required -define void @test3(i8* %dest) { +define void @test3(ptr %dest) { ; CHECK-LABEL: @test3( ; CHECK-NEXT: [[A:%.*]] = alloca [7 x i8], align 1 -; CHECK-NEXT: [[SRC:%.*]] = getelementptr inbounds [7 x i8], [7 x i8]* [[A]], i64 0, i64 0 -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DEST:%.*]], i8* [[SRC]], i64 7, i1 true) +; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[DEST:%.*]], ptr [[A]], i64 7, i1 true) ; CHECK-NEXT: ret void ; %a = alloca [7 x i8] - %src = getelementptr inbounds [7 x i8], [7 x i8]* %a, i64 0, i64 0 - call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dest, i8* %src, i64 7, i1 true) + call void @llvm.memcpy.p0.p0.i64(ptr %dest, ptr %a, i64 7, i1 true) ret void } -define void @test4(i8* %dest) { +define void @test4(ptr %dest) { ; CHECK-LABEL: @test4( ; CHECK-NEXT: ret void ; %a = alloca [7 x i8] - %src = bitcast [7 x i8]* %a to i8* - call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dest, i8* %src, i64 7, i1 false) + call void @llvm.memcpy.p0.p0.i64(ptr %dest, ptr %a, i64 7, i1 false) ret void } -define void @test5(i8* %dest) { +define void @test5(ptr %dest) { ; CHECK-LABEL: @test5( ; CHECK-NEXT: ret void ; %a = alloca [7 x i8] - %p1 = bitcast [7 x i8]* %a to i32* - %p2 = getelementptr i32, i32* %p1, i32 1 - %src = bitcast i32* %p2 to i8* - call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dest, i8* %src, i64 3, i1 false) + %p2 = getelementptr i32, ptr %a, i32 1 + call void @llvm.memcpy.p0.p0.i64(ptr %dest, ptr %p2, i64 3, i1 false) ret void } -define void @test6(i8* %dest) { +define void @test6(ptr %dest) { ; CHECK-LABEL: @test6( ; CHECK-NEXT: [[A:%.*]] = alloca [7 x i8], align 1 -; CHECK-NEXT: [[P2:%.*]] = getelementptr inbounds [7 x i8], [7 x i8]* [[A]], i64 0, i64 2 -; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[P2]] to i16* -; CHECK-NEXT: store i16 42, i16* [[TMP1]], align 2 -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(7) [[DEST:%.*]], i8* noundef nonnull align 1 dereferenceable(7) [[P2]], i64 7, i1 false) +; CHECK-NEXT: [[P2:%.*]] = getelementptr inbounds i16, ptr [[A]], i64 1 +; CHECK-NEXT: store i16 42, ptr [[P2]], align 2 +; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(7) [[DEST:%.*]], ptr noundef nonnull align 1 dereferenceable(7) [[P2]], i64 7, i1 false) ; CHECK-NEXT: ret void ; %a = alloca [7 x i8] - %p1 = bitcast [7 x i8]* %a to i16* - %p2 = getelementptr i16, i16* %p1, i32 1 - store i16 42, i16* %p2 - %src = bitcast i16* %p2 to i8* - call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dest, i8* %src, i64 7, i1 false) + %p2 = getelementptr i16, ptr %a, i32 1 + store i16 42, ptr %p2 + call void @llvm.memcpy.p0.p0.i64(ptr %dest, ptr %p2, i64 7, i1 false) ret void } -declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i1) +declare void @llvm.memcpy.p0.p0.i64(ptr, ptr, i64, i1) diff --git a/llvm/test/Transforms/InstCombine/memcpy_chk-1.ll b/llvm/test/Transforms/InstCombine/memcpy_chk-1.ll --- a/llvm/test/Transforms/InstCombine/memcpy_chk-1.ll +++ b/llvm/test/Transforms/InstCombine/memcpy_chk-1.ll @@ -16,94 +16,81 @@ ; Check cases where dstlen >= len. -define i8* @test_simplify1() { +define ptr @test_simplify1() { ; CHECK-LABEL: @test_simplify1( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 4 dereferenceable(1824) bitcast (%struct.T1* @t1 to i8*), i8* noundef nonnull align 4 dereferenceable(1824) bitcast (%struct.T2* @t2 to i8*), i64 1824, i1 false) -; CHECK-NEXT: ret i8* bitcast (%struct.T1* @t1 to i8*) +; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 4 dereferenceable(1824) @t1, ptr noundef nonnull align 4 dereferenceable(1824) @t2, i64 1824, i1 false) +; CHECK-NEXT: ret ptr @t1 ; - %dst = bitcast %struct.T1* @t1 to i8* - %src = bitcast %struct.T2* @t2 to i8* - %ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1824, i64 1824) - ret i8* %ret + %ret = call ptr @__memcpy_chk(ptr @t1, ptr @t2, i64 1824, i64 1824) + ret ptr %ret } -define i8* @test_simplify2() { +define ptr @test_simplify2() { ; CHECK-LABEL: @test_simplify2( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 4 dereferenceable(1824) bitcast (%struct.T1* @t1 to i8*), i8* noundef nonnull align 4 dereferenceable(1824) bitcast (%struct.T3* @t3 to i8*), i64 1824, i1 false) -; CHECK-NEXT: ret i8* bitcast (%struct.T1* @t1 to i8*) +; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 4 dereferenceable(1824) @t1, ptr noundef nonnull align 4 dereferenceable(1824) @t3, i64 1824, i1 false) +; CHECK-NEXT: ret ptr @t1 ; - %dst = bitcast %struct.T1* @t1 to i8* - %src = bitcast %struct.T3* @t3 to i8* - %ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1824, i64 2848) - ret i8* %ret + %ret = call ptr @__memcpy_chk(ptr @t1, ptr @t3, i64 1824, i64 2848) + ret ptr %ret } ; Same as test_simplify1 but with a tail call rather than vanilla call. -define i8* @test_simplify3() { +define ptr @test_simplify3() { ; CHECK-LABEL: @test_simplify3( -; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 4 dereferenceable(1824) bitcast (%struct.T1* @t1 to i8*), i8* noundef nonnull align 4 dereferenceable(1824) bitcast (%struct.T2* @t2 to i8*), i64 1824, i1 false) -; CHECK-NEXT: ret i8* bitcast (%struct.T1* @t1 to i8*) +; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 4 dereferenceable(1824) @t1, ptr noundef nonnull align 4 dereferenceable(1824) @t2, i64 1824, i1 false) +; CHECK-NEXT: ret ptr @t1 ; - %dst = bitcast %struct.T1* @t1 to i8* - %src = bitcast %struct.T2* @t2 to i8* - %ret = tail call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1824, i64 1824) - ret i8* %ret + %ret = tail call ptr @__memcpy_chk(ptr @t1, ptr @t2, i64 1824, i64 1824) + ret ptr %ret } ; Check cases where dstlen < len. -define i8* @test_no_simplify1() { +define ptr @test_no_simplify1() { ; CHECK-LABEL: @test_no_simplify1( -; CHECK-NEXT: [[RET:%.*]] = call i8* @__memcpy_chk(i8* bitcast (%struct.T3* @t3 to i8*), i8* bitcast (%struct.T1* @t1 to i8*), i64 2848, i64 1824) -; CHECK-NEXT: ret i8* [[RET]] +; CHECK-NEXT: [[RET:%.*]] = call ptr @__memcpy_chk(ptr nonnull @t3, ptr nonnull @t1, i64 2848, i64 1824) +; CHECK-NEXT: ret ptr [[RET]] ; - %dst = bitcast %struct.T3* @t3 to i8* - %src = bitcast %struct.T1* @t1 to i8* - %ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 2848, i64 1824) - ret i8* %ret + %ret = call ptr @__memcpy_chk(ptr @t3, ptr @t1, i64 2848, i64 1824) + ret ptr %ret } -define i8* @test_no_simplify2() { +define ptr @test_no_simplify2() { ; CHECK-LABEL: @test_no_simplify2( -; CHECK-NEXT: [[RET:%.*]] = call i8* @__memcpy_chk(i8* bitcast (%struct.T1* @t1 to i8*), i8* bitcast (%struct.T2* @t2 to i8*), i64 1024, i64 0) -; CHECK-NEXT: ret i8* [[RET]] +; CHECK-NEXT: [[RET:%.*]] = call ptr @__memcpy_chk(ptr nonnull @t1, ptr nonnull @t2, i64 1024, i64 0) +; CHECK-NEXT: ret ptr [[RET]] ; - %dst = bitcast %struct.T1* @t1 to i8* - %src = bitcast %struct.T2* @t2 to i8* - %ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1024, i64 0) - ret i8* %ret + %ret = call ptr @__memcpy_chk(ptr @t1, ptr @t2, i64 1024, i64 0) + ret ptr %ret } -define i8* @test_no_simplify3(i8* %dst, i8* %src, i64 %a, i64 %b) { +define ptr @test_no_simplify3(ptr %dst, ptr %src, i64 %a, i64 %b) { ; CHECK-LABEL: @test_no_simplify3( -; CHECK-NEXT: %ret = musttail call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1824, i64 1824) -; CHECK-NEXT: ret i8* %ret +; CHECK-NEXT: [[RET:%.*]] = musttail call ptr @__memcpy_chk(ptr [[DST:%.*]], ptr [[SRC:%.*]], i64 1824, i64 1824) +; CHECK-NEXT: ret ptr [[RET]] ; - %ret = musttail call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1824, i64 1824) - ret i8* %ret + %ret = musttail call ptr @__memcpy_chk(ptr %dst, ptr %src, i64 1824, i64 1824) + ret ptr %ret } -define i8* @test_simplify_return_indcall(i8* ()* %alloc) { +define ptr @test_simplify_return_indcall(ptr %alloc) { ; CHECK-LABEL: @test_simplify_return_indcall( -; CHECK-NEXT: [[DST:%.*]] = call i8* [[ALLOC:%.*]]() -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(1824) [[DST]], i8* noundef nonnull align 4 dereferenceable(1824) bitcast (%struct.T2* @t2 to i8*), i64 1824, i1 false) -; CHECK-NEXT: ret i8* [[DST]] +; CHECK-NEXT: [[DST:%.*]] = call ptr [[ALLOC:%.*]]() +; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(1824) [[DST]], ptr noundef nonnull align 4 dereferenceable(1824) @t2, i64 1824, i1 false) +; CHECK-NEXT: ret ptr [[DST]] ; - %src = bitcast %struct.T2* @t2 to i8* - %dst = call i8* %alloc() - %ret = call i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1824, i64 1824) - ret i8* %ret + %dst = call ptr %alloc() + %ret = call ptr @__memcpy_chk(ptr %dst, ptr @t2, i64 1824, i64 1824) + ret ptr %ret } -define i8* @test_no_incompatible_attr(i8* %mem, i32 %val, i32 %size) { +define ptr @test_no_incompatible_attr(ptr %mem, i32 %val, i32 %size) { ; CHECK-LABEL: @test_no_incompatible_attr( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 4 dereferenceable(1824) bitcast (%struct.T1* @t1 to i8*), i8* noundef nonnull align 4 dereferenceable(1824) bitcast (%struct.T2* @t2 to i8*), i64 1824, i1 false) -; CHECK-NEXT: ret i8* bitcast (%struct.T1* @t1 to i8*) +; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 4 dereferenceable(1824) @t1, ptr noundef nonnull align 4 dereferenceable(1824) @t2, i64 1824, i1 false) +; CHECK-NEXT: ret ptr @t1 ; - %dst = bitcast %struct.T1* @t1 to i8* - %src = bitcast %struct.T2* @t2 to i8* - %ret = call dereferenceable(1) i8* @__memcpy_chk(i8* %dst, i8* %src, i64 1824, i64 1824) - ret i8* %ret + %ret = call dereferenceable(1) ptr @__memcpy_chk(ptr @t1, ptr @t2, i64 1824, i64 1824) + ret ptr %ret } -declare i8* @__memcpy_chk(i8*, i8*, i64, i64) +declare ptr @__memcpy_chk(ptr, ptr, i64, i64) diff --git a/llvm/test/Transforms/InstCombine/simplify-libcalls-i16.ll b/llvm/test/Transforms/InstCombine/simplify-libcalls-i16.ll --- a/llvm/test/Transforms/InstCombine/simplify-libcalls-i16.ll +++ b/llvm/test/Transforms/InstCombine/simplify-libcalls-i16.ll @@ -3,23 +3,22 @@ ; RUN: opt -S < %s -mtriple=msp430 -passes=instcombine -instcombine-infinite-loop-threshold=2 | FileCheck -check-prefixes=CHECK,CHECK16 %s target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S32" -@G = constant [3 x i8] c"%s\00" ; <[3 x i8]*> [#uses=1] +@G = constant [3 x i8] c"%s\00" ; [#uses=1] ; A 16-bit compatible sprintf is not recognized as the standard library ; function on 32-bit targets. -declare i16 @sprintf(i8*, i8*, ...) +declare i16 @sprintf(ptr, ptr, ...) -define void @foo(i8* %P, i32* %X) { +define void @foo(ptr %P, ptr %X) { ; CHECK32-LABEL: @foo( -; CHECK32-NEXT: [[TMP1:%.*]] = call i16 (i8*, i8*, ...) @sprintf(i8* [[P:%.*]], i8* getelementptr inbounds ([3 x i8], [3 x i8]* @G, i32 0, i32 0), i32* [[X:%.*]]) +; CHECK32-NEXT: [[TMP1:%.*]] = call i16 (ptr, ptr, ...) @sprintf(ptr [[P:%.*]], ptr nonnull @G, ptr [[X:%.*]]) ; CHECK32-NEXT: ret void ; ; CHECK16-LABEL: @foo( -; CHECK16-NEXT: [[CSTR:%.*]] = bitcast i32* [[X:%.*]] to i8* -; CHECK16-NEXT: [[STRCPY:%.*]] = call i8* @strcpy(i8* noundef nonnull dereferenceable(1) [[P:%.*]], i8* noundef nonnull dereferenceable(1) [[CSTR]]) +; CHECK16-NEXT: [[STRCPY:%.*]] = call ptr @strcpy(ptr noundef nonnull dereferenceable(1) [[P:%.*]], ptr noundef nonnull dereferenceable(1) [[X:%.*]]) ; CHECK16-NEXT: ret void ; - call i16 (i8*, i8*, ...) @sprintf(i8* %P, i8* getelementptr ([3 x i8], [3 x i8]* @G, i32 0, i32 0), i32* %X ) ; :1 [#uses=0] + call i16 (ptr, ptr, ...) @sprintf(ptr %P, ptr @G, ptr %X ) ; :1 [#uses=0] ret void } @@ -28,67 +27,67 @@ @str1 = internal constant [8 x i8] c"blahhh!\00" @str2 = internal constant [5 x i8] c"Ponk\00" -define i8* @test1() { +define ptr @test1() { ; CHECK32-LABEL: @test1( -; CHECK32-NEXT: [[TMP3:%.*]] = tail call i8* @strchr(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @str, i32 0, i32 2), i16 103) -; CHECK32-NEXT: ret i8* [[TMP3]] +; CHECK32-NEXT: [[TMP3:%.*]] = tail call ptr @strchr(ptr getelementptr inbounds ([5 x i8], ptr @str, i32 0, i32 2), i16 103) +; CHECK32-NEXT: ret ptr [[TMP3]] ; ; CHECK16-LABEL: @test1( -; CHECK16-NEXT: ret i8* getelementptr inbounds ([5 x i8], [5 x i8]* @str, i32 0, i32 3) +; CHECK16-NEXT: ret ptr getelementptr inbounds ([5 x i8], ptr @str, i32 0, i32 3) ; - %tmp3 = tail call i8* @strchr( i8* getelementptr ([5 x i8], [5 x i8]* @str, i32 0, i16 2), i16 103 ) ; [#uses=1] - ret i8* %tmp3 + %tmp3 = tail call ptr @strchr( ptr getelementptr ([5 x i8], ptr @str, i32 0, i16 2), i16 103 ) ; [#uses=1] + ret ptr %tmp3 } ; A 16-bit compatible strchr is not recognized as the standard library ; function on 32-bit targets. -declare i8* @strchr(i8*, i16) +declare ptr @strchr(ptr, i16) -define i8* @test2() { +define ptr @test2() { ; CHECK32-LABEL: @test2( -; CHECK32-NEXT: [[TMP3:%.*]] = tail call i8* @strchr(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @str1, i32 0, i32 2), i16 0) -; CHECK32-NEXT: ret i8* [[TMP3]] +; CHECK32-NEXT: [[TMP3:%.*]] = tail call ptr @strchr(ptr getelementptr inbounds ([8 x i8], ptr @str1, i32 0, i32 2), i16 0) +; CHECK32-NEXT: ret ptr [[TMP3]] ; ; CHECK16-LABEL: @test2( -; CHECK16-NEXT: ret i8* getelementptr inbounds ([8 x i8], [8 x i8]* @str1, i32 0, i32 7) +; CHECK16-NEXT: ret ptr getelementptr inbounds ([8 x i8], ptr @str1, i32 0, i32 7) ; - %tmp3 = tail call i8* @strchr( i8* getelementptr ([8 x i8], [8 x i8]* @str1, i32 0, i32 2), i16 0 ) ; [#uses=1] - ret i8* %tmp3 + %tmp3 = tail call ptr @strchr( ptr getelementptr ([8 x i8], ptr @str1, i32 0, i32 2), i16 0 ) ; [#uses=1] + ret ptr %tmp3 } -define i8* @test3() { +define ptr @test3() { ; CHECK32-LABEL: @test3( ; CHECK32-NEXT: entry: -; CHECK32-NEXT: [[TMP3:%.*]] = tail call i8* @strchr(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @str2, i32 0, i32 1), i16 80) -; CHECK32-NEXT: ret i8* [[TMP3]] +; CHECK32-NEXT: [[TMP3:%.*]] = tail call ptr @strchr(ptr getelementptr inbounds ([5 x i8], ptr @str2, i32 0, i32 1), i16 80) +; CHECK32-NEXT: ret ptr [[TMP3]] ; ; CHECK16-LABEL: @test3( ; CHECK16-NEXT: entry: -; CHECK16-NEXT: ret i8* null +; CHECK16-NEXT: ret ptr null ; entry: - %tmp3 = tail call i8* @strchr( i8* getelementptr ([5 x i8], [5 x i8]* @str2, i32 0, i32 1), i16 80 ) ; [#uses=1] - ret i8* %tmp3 + %tmp3 = tail call ptr @strchr( ptr getelementptr ([5 x i8], ptr @str2, i32 0, i32 1), i16 80 ) ; [#uses=1] + ret ptr %tmp3 } -@_2E_str = external constant [5 x i8] ; <[5 x i8]*> [#uses=1] +@_2E_str = external constant [5 x i8] ; [#uses=1] ; A 16-bit compatible memcmp is not recognized as the standard library ; function on 32-bit targets. -declare i16 @memcmp(i8*, i8*, i16) nounwind readonly +declare i16 @memcmp(ptr, ptr, i16) nounwind readonly -define i1 @PR2341(i8** %start_addr) { +define i1 @PR2341(ptr %start_addr) { ; CHECK-LABEL: @PR2341( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP4:%.*]] = load i8*, i8** [[START_ADDR:%.*]], align 4 -; CHECK-NEXT: [[TMP5:%.*]] = call i16 @memcmp(i8* [[TMP4]], i8* getelementptr inbounds ([5 x i8], [5 x i8]* @_2E_str, i32 0, i32 0), i16 4) #[[ATTR0:[0-9]+]] +; CHECK-NEXT: [[TMP4:%.*]] = load ptr, ptr [[START_ADDR:%.*]], align 4 +; CHECK-NEXT: [[TMP5:%.*]] = call i16 @memcmp(ptr [[TMP4]], ptr nonnull @_2E_str, i16 4) #[[ATTR0:[0-9]+]] ; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i16 [[TMP5]], 0 ; CHECK-NEXT: ret i1 [[TMP6]] ; entry: - %tmp4 = load i8*, i8** %start_addr, align 4 ; [#uses=1] - %tmp5 = call i16 @memcmp( i8* %tmp4, i8* getelementptr ([5 x i8], [5 x i8]* @_2E_str, i32 0, i32 0), i16 4 ) nounwind readonly ; [#uses=1] + %tmp4 = load ptr, ptr %start_addr, align 4 ; [#uses=1] + %tmp5 = call i16 @memcmp( ptr %tmp4, ptr @_2E_str, i16 4 ) nounwind readonly ; [#uses=1] %tmp6 = icmp eq i16 %tmp5, 0 ; [#uses=1] ret i1 %tmp6 @@ -99,45 +98,45 @@ ; CHECK-NEXT: entry: ; CHECK-NEXT: [[C0:%.*]] = alloca i8, align 1 ; CHECK-NEXT: [[C2:%.*]] = alloca i8, align 1 -; CHECK-NEXT: store i8 64, i8* [[C0]], align 1 -; CHECK-NEXT: store i8 -127, i8* [[C2]], align 1 -; CHECK-NEXT: [[CALL:%.*]] = call i16 @memcmp(i8* nonnull [[C0]], i8* nonnull [[C2]], i16 1) +; CHECK-NEXT: store i8 64, ptr [[C0]], align 1 +; CHECK-NEXT: store i8 -127, ptr [[C2]], align 1 +; CHECK-NEXT: [[CALL:%.*]] = call i16 @memcmp(ptr nonnull [[C0]], ptr nonnull [[C2]], i16 1) ; CHECK-NEXT: ret i16 [[CALL]] ; entry: - %c0 = alloca i8, align 1 ; [#uses=2] - %c2 = alloca i8, align 1 ; [#uses=2] - store i8 64, i8* %c0 - store i8 -127, i8* %c2 - %call = call i16 @memcmp(i8* %c0, i8* %c2, i16 1) ; [#uses=1] + %c0 = alloca i8, align 1 ; [#uses=2] + %c2 = alloca i8, align 1 ; [#uses=2] + store i8 64, ptr %c0 + store i8 -127, ptr %c2 + %call = call i16 @memcmp(ptr %c0, ptr %c2, i16 1) ; [#uses=1] ret i16 %call } -%struct.__sFILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, i8*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64, %struct.pthread_mutex*, %struct.pthread*, i32, i32, %union.anon } -%struct.__sbuf = type { i8*, i32, [4 x i8] } +%struct.__sFILE = type { ptr, i32, i32, i16, i16, %struct.__sbuf, i32, ptr, ptr, ptr, ptr, ptr, %struct.__sbuf, ptr, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64, ptr, ptr, i32, i32, %union.anon } +%struct.__sbuf = type { ptr, i32, [4 x i8] } %struct.pthread = type opaque %struct.pthread_mutex = type opaque %union.anon = type { i64, [120 x i8] } -@.str13 = external constant [2 x i8] ; <[2 x i8]*> [#uses=1] -@.str14 = external constant [2 x i8] ; <[2 x i8]*> [#uses=1] +@.str13 = external constant [2 x i8] ; [#uses=1] +@.str14 = external constant [2 x i8] ; [#uses=1] -define i32 @PR4641(i32 %argc, i8** %argv, i1 %c1, i8* %ptr) nounwind { +define i32 @PR4641(i32 %argc, ptr %argv, i1 %c1, ptr %ptr) nounwind { ; CHECK-LABEL: @PR4641( ; CHECK-NEXT: entry: ; CHECK-NEXT: call void @exit(i16 0) #[[ATTR1:[0-9]+]] -; CHECK-NEXT: [[COND392:%.*]] = select i1 [[C1:%.*]], i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str13, i32 0, i32 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str14, i32 0, i32 0) -; CHECK-NEXT: [[CALL393:%.*]] = call %struct.__sFILE* @fopen(i8* [[PTR:%.*]], i8* [[COND392]]) #[[ATTR1]] +; CHECK-NEXT: [[COND392:%.*]] = select i1 [[C1:%.*]], ptr @.str13, ptr @.str14 +; CHECK-NEXT: [[CALL393:%.*]] = call ptr @fopen(ptr [[PTR:%.*]], ptr nonnull [[COND392]]) #[[ATTR1]] ; CHECK-NEXT: unreachable ; entry: call void @exit(i16 0) nounwind - %cond392 = select i1 %c1, i8* getelementptr ([2 x i8], [2 x i8]* @.str13, i32 0, i32 0), i8* getelementptr ([2 x i8], [2 x i8]* @.str14, i32 0, i32 0) ; [#uses=1] - %call393 = call %struct.__sFILE* @fopen(i8* %ptr, i8* %cond392) nounwind ; <%struct.__sFILE*> [#uses=0] + %cond392 = select i1 %c1, ptr @.str13, ptr @.str14 ; [#uses=1] + %call393 = call ptr @fopen(ptr %ptr, ptr %cond392) nounwind ; [#uses=0] unreachable } -declare %struct.__sFILE* @fopen(i8*, i8*) +declare ptr @fopen(ptr, ptr) ; A 16-bit compatible exit is not recognized as the standard library ; function on 32-bit targets. @@ -176,41 +175,37 @@ br label %for.cond } -@h = constant [2 x i8] c"h\00" ; <[2 x i8]*> [#uses=1] -@hel = constant [4 x i8] c"hel\00" ; <[4 x i8]*> [#uses=1] -@hello_u = constant [8 x i8] c"hello_u\00" ; <[8 x i8]*> [#uses=1] +@h = constant [2 x i8] c"h\00" ; [#uses=1] +@hel = constant [4 x i8] c"hel\00" ; [#uses=1] +@hello_u = constant [8 x i8] c"hello_u\00" ; [#uses=1] define i32 @MemCpy() { ; CHECK-LABEL: @MemCpy( ; CHECK-NEXT: ret i32 0 ; - %h_p = getelementptr [2 x i8], [2 x i8]* @h, i32 0, i32 0 - %hel_p = getelementptr [4 x i8], [4 x i8]* @hel, i32 0, i32 0 - %hello_u_p = getelementptr [8 x i8], [8 x i8]* @hello_u, i32 0, i32 0 %target = alloca [1024 x i8] - %target_p = getelementptr [1024 x i8], [1024 x i8]* %target, i32 0, i32 0 - call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 %target_p, i8* align 2 %h_p, i16 2, i1 false) - call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %target_p, i8* align 4 %hel_p, i16 4, i1 false) - call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %target_p, i8* align 8 %hello_u_p, i16 8, i1 false) + call void @llvm.memcpy.p0.p0.i32(ptr align 2 %target, ptr align 2 @h, i16 2, i1 false) + call void @llvm.memcpy.p0.p0.i32(ptr align 4 %target, ptr align 4 @hel, i16 4, i1 false) + call void @llvm.memcpy.p0.p0.i32(ptr align 8 %target, ptr align 8 @hello_u, i16 8, i1 false) ret i32 0 } -declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i16, i1) +declare void @llvm.memcpy.p0.p0.i32(ptr nocapture, ptr nocapture, i16, i1) ; A 16-bit compatible strcmp is not recognized as the standard library ; function on 32-bit targets. -declare i16 @strcmp(i8*, i8*) #0 +declare i16 @strcmp(ptr, ptr) #0 -define void @test9(i8* %x) { +define void @test9(ptr %x) { ; CHECK32-LABEL: @test9( -; CHECK32-NEXT: [[Y:%.*]] = call i16 @strcmp(i8* [[X:%.*]], i8* [[X]]) #[[ATTR6:[0-9]+]] +; CHECK32-NEXT: [[Y:%.*]] = call i16 @strcmp(ptr [[X:%.*]], ptr [[X]]) #[[ATTR6:[0-9]+]] ; CHECK32-NEXT: ret void ; ; CHECK16-LABEL: @test9( ; CHECK16-NEXT: ret void ; - %y = call i16 @strcmp(i8* %x, i8* %x) #1 + %y = call i16 @strcmp(ptr %x, ptr %x) #1 ret void } @@ -298,40 +293,40 @@ ; A 16-bit compatible snprintf is not recognized as the standard library ; function on 32-bit targets. -declare i16 @snprintf(i8*, double, i32*) +declare i16 @snprintf(ptr, double, ptr) -define i16 @fake_snprintf(i32 %buf, double %len, i32 * %str, i8* %ptr) { +define i16 @fake_snprintf(i32 %buf, double %len, ptr %str, ptr %ptr) { ; CHECK-LABEL: @fake_snprintf( -; CHECK-NEXT: [[CALL:%.*]] = call i16 @snprintf(i8* [[PTR:%.*]], double [[LEN:%.*]], i32* [[STR:%.*]]) +; CHECK-NEXT: [[CALL:%.*]] = call i16 @snprintf(ptr [[PTR:%.*]], double [[LEN:%.*]], ptr [[STR:%.*]]) ; CHECK-NEXT: ret i16 [[CALL]] ; - %call = call i16 @snprintf(i8* %ptr, double %len, i32* %str) + %call = call i16 @snprintf(ptr %ptr, double %len, ptr %str) ret i16 %call } ; Wrong return type for the real strlen. ; https://llvm.org/PR50836 -define i4 @strlen(i8* %s) { +define i4 @strlen(ptr %s) { ; CHECK-LABEL: @strlen( -; CHECK-NEXT: [[R:%.*]] = call i4 @strlen(i8* [[S:%.*]]) +; CHECK-NEXT: [[R:%.*]] = call i4 @strlen(ptr [[S:%.*]]) ; CHECK-NEXT: ret i4 0 ; - %r = call i4 @strlen(i8* %s) + %r = call i4 @strlen(ptr %s) ret i4 0 } ; Test emission of stpncpy, including call attributes. @a = dso_local global [4 x i8] c"123\00" @b = dso_local global [5 x i8] zeroinitializer -declare i8* @__stpncpy_chk(i8* noundef, i8* noundef, i32 noundef, i32 noundef) +declare ptr @__stpncpy_chk(ptr noundef, ptr noundef, i32 noundef, i32 noundef) define signext i32 @emit_stpncpy() { ; CHECK-LABEL: @emit_stpncpy( -; CHECK-NEXT: [[STPNCPY:%.*]] = call i8* @stpncpy(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x i8], [5 x i8]* @b, i32 0, i32 0), i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([4 x i8], [4 x i8]* @a, i32 0, i32 0), i32 2) +; CHECK-NEXT: [[STPNCPY:%.*]] = call ptr @stpncpy(ptr noundef nonnull dereferenceable(1) @b, ptr noundef nonnull dereferenceable(1) @a, i32 2) ; CHECK-NEXT: ret i32 0 ; - %call = call i8* @__stpncpy_chk(i8* noundef getelementptr inbounds ([5 x i8], [5 x i8]* @b, i32 0, i32 0), - i8* noundef getelementptr inbounds ([4 x i8], [4 x i8]* @a, i32 0, i32 0), + %call = call ptr @__stpncpy_chk(ptr noundef @b, + ptr noundef @a, i32 noundef 2, i32 noundef 5) ret i32 0 } diff --git a/llvm/test/Transforms/InstCombine/simplify-libcalls.ll b/llvm/test/Transforms/InstCombine/simplify-libcalls.ll --- a/llvm/test/Transforms/InstCombine/simplify-libcalls.ll +++ b/llvm/test/Transforms/InstCombine/simplify-libcalls.ll @@ -3,23 +3,22 @@ ; RUN: opt -S < %s -mtriple=msp430 -passes=instcombine -instcombine-infinite-loop-threshold=2 | FileCheck -check-prefixes=CHECK,CHECK16 %s target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S32" -@G = constant [3 x i8] c"%s\00" ; <[3 x i8]*> [#uses=1] +@G = constant [3 x i8] c"%s\00" ; [#uses=1] ; A 32-bit compatible sprintf is not recognized as the standard library ; function on 16-bit targets. -declare i32 @sprintf(i8*, i8*, ...) +declare i32 @sprintf(ptr, ptr, ...) -define void @foo(i8* %P, i32* %X) { +define void @foo(ptr %P, ptr %X) { ; CHECK32-LABEL: @foo( -; CHECK32-NEXT: [[CSTR:%.*]] = bitcast i32* [[X:%.*]] to i8* -; CHECK32-NEXT: [[STRCPY:%.*]] = call i8* @strcpy(i8* noundef nonnull dereferenceable(1) [[P:%.*]], i8* noundef nonnull dereferenceable(1) [[CSTR]]) +; CHECK32-NEXT: [[STRCPY:%.*]] = call ptr @strcpy(ptr noundef nonnull dereferenceable(1) [[P:%.*]], ptr noundef nonnull dereferenceable(1) [[X:%.*]]) ; CHECK32-NEXT: ret void ; ; CHECK16-LABEL: @foo( -; CHECK16-NEXT: [[TMP1:%.*]] = call i32 (i8*, i8*, ...) @sprintf(i8* [[P:%.*]], i8* getelementptr inbounds ([3 x i8], [3 x i8]* @G, i32 0, i32 0), i32* [[X:%.*]]) +; CHECK16-NEXT: [[TMP1:%.*]] = call i32 (ptr, ptr, ...) @sprintf(ptr [[P:%.*]], ptr nonnull @G, ptr [[X:%.*]]) ; CHECK16-NEXT: ret void ; - call i32 (i8*, i8*, ...) @sprintf( i8* %P, i8* getelementptr ([3 x i8], [3 x i8]* @G, i32 0, i32 0), i32* %X ) ; :1 [#uses=0] + call i32 (ptr, ptr, ...) @sprintf( ptr %P, ptr @G, ptr %X ) ; :1 [#uses=0] ret void } @@ -28,74 +27,74 @@ @str1 = internal constant [8 x i8] c"blahhh!\00" @str2 = internal constant [5 x i8] c"Ponk\00" -define i8* @test1() { +define ptr @test1() { ; CHECK32-LABEL: @test1( -; CHECK32-NEXT: ret i8* getelementptr inbounds ([5 x i8], [5 x i8]* @str, i32 0, i32 3) +; CHECK32-NEXT: ret ptr getelementptr inbounds ([5 x i8], ptr @str, i32 0, i32 3) ; ; CHECK16-LABEL: @test1( -; CHECK16-NEXT: [[TMP3:%.*]] = tail call i8* @strchr(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @str, i32 0, i32 2), i32 103) -; CHECK16-NEXT: ret i8* [[TMP3]] +; CHECK16-NEXT: [[TMP3:%.*]] = tail call ptr @strchr(ptr getelementptr inbounds ([5 x i8], ptr @str, i32 0, i32 2), i32 103) +; CHECK16-NEXT: ret ptr [[TMP3]] ; - %tmp3 = tail call i8* @strchr( i8* getelementptr ([5 x i8], [5 x i8]* @str, i32 0, i32 2), i32 103 ) ; [#uses=1] - ret i8* %tmp3 + %tmp3 = tail call ptr @strchr( ptr getelementptr ([5 x i8], ptr @str, i32 0, i32 2), i32 103 ) ; [#uses=1] + ret ptr %tmp3 } ; A 32-bit compatible strchr is not recognized as the standard library ; function on 16-bit targets. -declare i8* @strchr(i8*, i32) +declare ptr @strchr(ptr, i32) -define i8* @test2() { +define ptr @test2() { ; CHECK32-LABEL: @test2( -; CHECK32-NEXT: ret i8* getelementptr inbounds ([8 x i8], [8 x i8]* @str1, i32 0, i32 7) +; CHECK32-NEXT: ret ptr getelementptr inbounds ([8 x i8], ptr @str1, i32 0, i32 7) ; ; CHECK16-LABEL: @test2( -; CHECK16-NEXT: [[TMP3:%.*]] = tail call i8* @strchr(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @str1, i32 0, i32 2), i32 0) -; CHECK16-NEXT: ret i8* [[TMP3]] +; CHECK16-NEXT: [[TMP3:%.*]] = tail call ptr @strchr(ptr getelementptr inbounds ([8 x i8], ptr @str1, i32 0, i32 2), i32 0) +; CHECK16-NEXT: ret ptr [[TMP3]] ; - %tmp3 = tail call i8* @strchr( i8* getelementptr ([8 x i8], [8 x i8]* @str1, i32 0, i32 2), i32 0 ) ; [#uses=1] - ret i8* %tmp3 + %tmp3 = tail call ptr @strchr( ptr getelementptr ([8 x i8], ptr @str1, i32 0, i32 2), i32 0 ) ; [#uses=1] + ret ptr %tmp3 } -define i8* @test3() { +define ptr @test3() { ; CHECK32-LABEL: @test3( ; CHECK32-NEXT: entry: -; CHECK32-NEXT: ret i8* null +; CHECK32-NEXT: ret ptr null ; ; CHECK16-LABEL: @test3( ; CHECK16-NEXT: entry: -; CHECK16-NEXT: [[TMP3:%.*]] = tail call i8* @strchr(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @str2, i32 0, i32 1), i32 80) -; CHECK16-NEXT: ret i8* [[TMP3]] +; CHECK16-NEXT: [[TMP3:%.*]] = tail call ptr @strchr(ptr getelementptr inbounds ([5 x i8], ptr @str2, i32 0, i32 1), i32 80) +; CHECK16-NEXT: ret ptr [[TMP3]] ; entry: - %tmp3 = tail call i8* @strchr( i8* getelementptr ([5 x i8], [5 x i8]* @str2, i32 0, i32 1), i32 80 ) ; [#uses=1] - ret i8* %tmp3 + %tmp3 = tail call ptr @strchr( ptr getelementptr ([5 x i8], ptr @str2, i32 0, i32 1), i32 80 ) ; [#uses=1] + ret ptr %tmp3 } -@_2E_str = external constant [5 x i8] ; <[5 x i8]*> [#uses=1] +@_2E_str = external constant [5 x i8] ; [#uses=1] ; A 32-bit compatible memcmp is not recognized as the standard library ; function on 16-bit targets. -declare i32 @memcmp(i8*, i8*, i32) nounwind readonly +declare i32 @memcmp(ptr, ptr, i32) nounwind readonly -define i1 @PR2341(i8** %start_addr) { +define i1 @PR2341(ptr %start_addr) { ; CHECK32-LABEL: @PR2341( ; CHECK32-NEXT: entry: -; CHECK32-NEXT: [[TMP4:%.*]] = load i8*, i8** [[START_ADDR:%.*]], align 4 -; CHECK32-NEXT: [[TMP5:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(4) [[TMP4]], i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([5 x i8], [5 x i8]* @_2E_str, i32 0, i32 0), i32 4) #[[ATTR0:[0-9]+]] +; CHECK32-NEXT: [[TMP4:%.*]] = load ptr, ptr [[START_ADDR:%.*]], align 4 +; CHECK32-NEXT: [[TMP5:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) [[TMP4]], ptr noundef nonnull dereferenceable(4) @_2E_str, i32 4) #[[ATTR0:[0-9]+]] ; CHECK32-NEXT: [[TMP6:%.*]] = icmp eq i32 [[TMP5]], 0 ; CHECK32-NEXT: ret i1 [[TMP6]] ; ; CHECK16-LABEL: @PR2341( ; CHECK16-NEXT: entry: -; CHECK16-NEXT: [[TMP4:%.*]] = load i8*, i8** [[START_ADDR:%.*]], align 4 -; CHECK16-NEXT: [[TMP5:%.*]] = call i32 @memcmp(i8* [[TMP4]], i8* getelementptr inbounds ([5 x i8], [5 x i8]* @_2E_str, i32 0, i32 0), i32 4) #[[ATTR0:[0-9]+]] +; CHECK16-NEXT: [[TMP4:%.*]] = load ptr, ptr [[START_ADDR:%.*]], align 4 +; CHECK16-NEXT: [[TMP5:%.*]] = call i32 @memcmp(ptr [[TMP4]], ptr nonnull @_2E_str, i32 4) #[[ATTR0:[0-9]+]] ; CHECK16-NEXT: [[TMP6:%.*]] = icmp eq i32 [[TMP5]], 0 ; CHECK16-NEXT: ret i1 [[TMP6]] ; entry: - %tmp4 = load i8*, i8** %start_addr, align 4 ; [#uses=1] - %tmp5 = call i32 @memcmp( i8* %tmp4, i8* getelementptr ([5 x i8], [5 x i8]* @_2E_str, i32 0, i32 0), i32 4 ) nounwind readonly ; [#uses=1] + %tmp4 = load ptr, ptr %start_addr, align 4 ; [#uses=1] + %tmp5 = call i32 @memcmp( ptr %tmp4, ptr @_2E_str, i32 4 ) nounwind readonly ; [#uses=1] %tmp6 = icmp eq i32 %tmp5, 0 ; [#uses=1] ret i1 %tmp6 @@ -110,45 +109,45 @@ ; CHECK16-NEXT: entry: ; CHECK16-NEXT: [[C0:%.*]] = alloca i8, align 1 ; CHECK16-NEXT: [[C2:%.*]] = alloca i8, align 1 -; CHECK16-NEXT: store i8 64, i8* [[C0]], align 1 -; CHECK16-NEXT: store i8 -127, i8* [[C2]], align 1 -; CHECK16-NEXT: [[CALL:%.*]] = call i32 @memcmp(i8* nonnull [[C0]], i8* nonnull [[C2]], i32 1) +; CHECK16-NEXT: store i8 64, ptr [[C0]], align 1 +; CHECK16-NEXT: store i8 -127, ptr [[C2]], align 1 +; CHECK16-NEXT: [[CALL:%.*]] = call i32 @memcmp(ptr nonnull [[C0]], ptr nonnull [[C2]], i32 1) ; CHECK16-NEXT: ret i32 [[CALL]] ; entry: - %c0 = alloca i8, align 1 ; [#uses=2] - %c2 = alloca i8, align 1 ; [#uses=2] - store i8 64, i8* %c0 - store i8 -127, i8* %c2 - %call = call i32 @memcmp(i8* %c0, i8* %c2, i32 1) ; [#uses=1] + %c0 = alloca i8, align 1 ; [#uses=2] + %c2 = alloca i8, align 1 ; [#uses=2] + store i8 64, ptr %c0 + store i8 -127, ptr %c2 + %call = call i32 @memcmp(ptr %c0, ptr %c2, i32 1) ; [#uses=1] ret i32 %call } -%struct.__sFILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, i8*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64, %struct.pthread_mutex*, %struct.pthread*, i32, i32, %union.anon } -%struct.__sbuf = type { i8*, i32, [4 x i8] } +%struct.__sFILE = type { ptr, i32, i32, i16, i16, %struct.__sbuf, i32, ptr, ptr, ptr, ptr, ptr, %struct.__sbuf, ptr, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64, ptr, ptr, i32, i32, %union.anon } +%struct.__sbuf = type { ptr, i32, [4 x i8] } %struct.pthread = type opaque %struct.pthread_mutex = type opaque %union.anon = type { i64, [120 x i8] } -@.str13 = external constant [2 x i8] ; <[2 x i8]*> [#uses=1] -@.str14 = external constant [2 x i8] ; <[2 x i8]*> [#uses=1] +@.str13 = external constant [2 x i8] ; [#uses=1] +@.str14 = external constant [2 x i8] ; [#uses=1] -define i32 @PR4641(i32 %argc, i8** %argv, i1 %c1, i8* %ptr) nounwind { +define i32 @PR4641(i32 %argc, ptr %argv, i1 %c1, ptr %ptr) nounwind { ; CHECK-LABEL: @PR4641( ; CHECK-NEXT: entry: ; CHECK-NEXT: call void @exit(i32 0) #[[ATTR1:[0-9]+]] -; CHECK-NEXT: [[COND392:%.*]] = select i1 [[C1:%.*]], i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str13, i32 0, i32 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str14, i32 0, i32 0) -; CHECK-NEXT: [[CALL393:%.*]] = call %struct.__sFILE* @fopen(i8* [[PTR:%.*]], i8* [[COND392]]) #[[ATTR1]] +; CHECK-NEXT: [[COND392:%.*]] = select i1 [[C1:%.*]], ptr @.str13, ptr @.str14 +; CHECK-NEXT: [[CALL393:%.*]] = call ptr @fopen(ptr [[PTR:%.*]], ptr nonnull [[COND392]]) #[[ATTR1]] ; CHECK-NEXT: unreachable ; entry: call void @exit(i32 0) nounwind - %cond392 = select i1 %c1, i8* getelementptr ([2 x i8], [2 x i8]* @.str13, i32 0, i32 0), i8* getelementptr ([2 x i8], [2 x i8]* @.str14, i32 0, i32 0) ; [#uses=1] - %call393 = call %struct.__sFILE* @fopen(i8* %ptr, i8* %cond392) nounwind ; <%struct.__sFILE*> [#uses=0] + %cond392 = select i1 %c1, ptr @.str13, ptr @.str14 ; [#uses=1] + %call393 = call ptr @fopen(ptr %ptr, ptr %cond392) nounwind ; [#uses=0] unreachable } -declare %struct.__sFILE* @fopen(i8*, i8*) +declare ptr @fopen(ptr, ptr) ; A 32-bit compatible exit is not recognized as the standard library ; function on 16-bit targets. @@ -187,41 +186,37 @@ br label %for.cond } -@h = constant [2 x i8] c"h\00" ; <[2 x i8]*> [#uses=1] -@hel = constant [4 x i8] c"hel\00" ; <[4 x i8]*> [#uses=1] -@hello_u = constant [8 x i8] c"hello_u\00" ; <[8 x i8]*> [#uses=1] +@h = constant [2 x i8] c"h\00" ; [#uses=1] +@hel = constant [4 x i8] c"hel\00" ; [#uses=1] +@hello_u = constant [8 x i8] c"hello_u\00" ; [#uses=1] define i32 @MemCpy() { ; CHECK-LABEL: @MemCpy( ; CHECK-NEXT: ret i32 0 ; - %h_p = getelementptr [2 x i8], [2 x i8]* @h, i32 0, i32 0 - %hel_p = getelementptr [4 x i8], [4 x i8]* @hel, i32 0, i32 0 - %hello_u_p = getelementptr [8 x i8], [8 x i8]* @hello_u, i32 0, i32 0 %target = alloca [1024 x i8] - %target_p = getelementptr [1024 x i8], [1024 x i8]* %target, i32 0, i32 0 - call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 2 %target_p, i8* align 2 %h_p, i32 2, i1 false) - call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %target_p, i8* align 4 %hel_p, i32 4, i1 false) - call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %target_p, i8* align 8 %hello_u_p, i32 8, i1 false) + call void @llvm.memcpy.p0.p0.i32(ptr align 2 %target, ptr align 2 @h, i32 2, i1 false) + call void @llvm.memcpy.p0.p0.i32(ptr align 4 %target, ptr align 4 @hel, i32 4, i1 false) + call void @llvm.memcpy.p0.p0.i32(ptr align 8 %target, ptr align 8 @hello_u, i32 8, i1 false) ret i32 0 } -declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i1) nounwind +declare void @llvm.memcpy.p0.p0.i32(ptr nocapture, ptr nocapture, i32, i1) nounwind ; A 32-bit compatible strcmp is not recognized as the standard library ; function on 16-bit targets. -declare i32 @strcmp(i8*, i8*) #0 +declare i32 @strcmp(ptr, ptr) #0 -define void @test9(i8* %x) { +define void @test9(ptr %x) { ; CHECK32-LABEL: @test9( ; CHECK32-NEXT: ret void ; ; CHECK16-LABEL: @test9( -; CHECK16-NEXT: [[Y:%.*]] = call i32 @strcmp(i8* [[X:%.*]], i8* [[X]]) #[[ATTR5:[0-9]+]] +; CHECK16-NEXT: [[Y:%.*]] = call i32 @strcmp(ptr [[X:%.*]], ptr [[X]]) #[[ATTR6:[0-9]+]] ; CHECK16-NEXT: ret void ; - %y = call i32 @strcmp(i8* %x, i8* %x) #1 + %y = call i32 @strcmp(ptr %x, ptr %x) #1 ret void } @@ -309,40 +304,40 @@ ; A 32-bit compatible snprintf is not recognized as the standard library ; function on 16-bit targets. -declare i32 @snprintf(i8*, double, i32*) +declare i32 @snprintf(ptr, double, ptr) -define i32 @fake_snprintf(i32 %buf, double %len, i32 * %str, i8* %ptr) { +define i32 @fake_snprintf(i32 %buf, double %len, ptr %str, ptr %ptr) { ; CHECK-LABEL: @fake_snprintf( -; CHECK-NEXT: [[CALL:%.*]] = call i32 @snprintf(i8* [[PTR:%.*]], double [[LEN:%.*]], i32* [[STR:%.*]]) +; CHECK-NEXT: [[CALL:%.*]] = call i32 @snprintf(ptr [[PTR:%.*]], double [[LEN:%.*]], ptr [[STR:%.*]]) ; CHECK-NEXT: ret i32 [[CALL]] ; - %call = call i32 @snprintf(i8* %ptr, double %len, i32* %str) + %call = call i32 @snprintf(ptr %ptr, double %len, ptr %str) ret i32 %call } ; Wrong return type for the real strlen. ; https://llvm.org/PR50836 -define i4 @strlen(i8* %s) { +define i4 @strlen(ptr %s) { ; CHECK-LABEL: @strlen( -; CHECK-NEXT: [[R:%.*]] = call i4 @strlen(i8* [[S:%.*]]) +; CHECK-NEXT: [[R:%.*]] = call i4 @strlen(ptr [[S:%.*]]) ; CHECK-NEXT: ret i4 0 ; - %r = call i4 @strlen(i8* %s) + %r = call i4 @strlen(ptr %s) ret i4 0 } ; Test emission of stpncpy. @a = dso_local global [4 x i8] c"123\00" @b = dso_local global [5 x i8] zeroinitializer -declare i8* @__stpncpy_chk(i8* noundef, i8* noundef, i32 noundef, i32 noundef) +declare ptr @__stpncpy_chk(ptr noundef, ptr noundef, i32 noundef, i32 noundef) define signext i32 @emit_stpncpy() { ; CHECK-LABEL: @emit_stpncpy( -; CHECK-NEXT: [[STPNCPY:%.*]] = call i8* @stpncpy(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x i8], [5 x i8]* @b, i32 0, i32 0), i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([4 x i8], [4 x i8]* @a, i32 0, i32 0), i32 2) +; CHECK-NEXT: [[STPNCPY:%.*]] = call ptr @stpncpy(ptr noundef nonnull dereferenceable(1) @b, ptr noundef nonnull dereferenceable(1) @a, i32 2) ; CHECK-NEXT: ret i32 0 ; - %call = call i8* @__stpncpy_chk(i8* noundef getelementptr inbounds ([5 x i8], [5 x i8]* @b, i32 0, i32 0), - i8* noundef getelementptr inbounds ([4 x i8], [4 x i8]* @a, i32 0, i32 0), + %call = call ptr @__stpncpy_chk(ptr noundef @b, + ptr noundef @a, i32 noundef 2, i32 noundef 5) ret i32 0 } diff --git a/llvm/test/Transforms/InstCombine/str-int-2.ll b/llvm/test/Transforms/InstCombine/str-int-2.ll --- a/llvm/test/Transforms/InstCombine/str-int-2.ll +++ b/llvm/test/Transforms/InstCombine/str-int-2.ll @@ -10,17 +10,17 @@ @.str.6 = private unnamed_addr constant [10 x i8] c"499496729\00", align 1 @.str.7 = private unnamed_addr constant [11 x i8] c"4994967295\00", align 1 -declare i64 @strtol(i8*, i8**, i32) -declare i32 @atoi(i8*) -declare i64 @atol(i8*) -declare i64 @atoll(i8*) -declare i64 @strtoll(i8*, i8**, i32) +declare i64 @strtol(ptr, ptr, i32) +declare i32 @atoi(ptr) +declare i64 @atol(ptr) +declare i64 @atoll(ptr) +declare i64 @strtoll(ptr, ptr, i32) define i64 @strtol_dec() #0 { ; CHECK-LABEL: @strtol_dec( ; CHECK-NEXT: ret i64 12 ; - %call = call i64 @strtol(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i8** null, i32 10) #2 + %call = call i64 @strtol(ptr @.str, ptr null, i32 10) #2 ret i64 %call } @@ -28,7 +28,7 @@ ; CHECK-LABEL: @strtol_base_zero( ; CHECK-NEXT: ret i64 12 ; - %call = call i64 @strtol(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i8** null, i32 0) #2 + %call = call i64 @strtol(ptr @.str, ptr null, i32 0) #2 ret i64 %call } @@ -36,29 +36,29 @@ ; CHECK-LABEL: @strtol_hex( ; CHECK-NEXT: ret i64 18 ; - %call = call i64 @strtol(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i8** null, i32 16) #2 + %call = call i64 @strtol(ptr @.str, ptr null, i32 16) #2 ret i64 %call } ; Fold a call to strtol with an endptr known to be nonnull. -define i64 @strtol_endptr_not_null(i8** nonnull %pend) { +define i64 @strtol_endptr_not_null(ptr nonnull %pend) { ; CHECK-LABEL: @strtol_endptr_not_null( -; CHECK-NEXT: store i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 2), i8** [[PEND:%.*]], align 8 +; CHECK-NEXT: store ptr getelementptr inbounds ([3 x i8], ptr @.str, i64 0, i64 2), ptr [[PEND:%.*]], align 8 ; CHECK-NEXT: ret i64 12 ; - %call = call i64 @strtol(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i8** %pend, i32 10) + %call = call i64 @strtol(ptr @.str, ptr %pend, i32 10) ret i64 %call } ; Don't fold a call to strtol with an endptr that's not known to be nonnull. -define i64 @strtol_endptr_maybe_null(i8** %end) { +define i64 @strtol_endptr_maybe_null(ptr %end) { ; CHECK-LABEL: @strtol_endptr_maybe_null( -; CHECK-NEXT: [[CALL:%.*]] = call i64 @strtol(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0), i8** [[END:%.*]], i32 10) +; CHECK-NEXT: [[CALL:%.*]] = call i64 @strtol(ptr nonnull @.str.1, ptr [[END:%.*]], i32 10) ; CHECK-NEXT: ret i64 [[CALL]] ; - %call = call i64 @strtol(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i32 0, i32 0), i8** %end, i32 10) + %call = call i64 @strtol(ptr @.str.1, ptr %end, i32 10) ret i64 %call } @@ -66,34 +66,34 @@ ; CHECK-LABEL: @atoi_test( ; CHECK-NEXT: ret i32 12 ; - %call = call i32 @atoi(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0)) #4 + %call = call i32 @atoi(ptr @.str) #4 ret i32 %call } -define i64 @strtol_not_const_str(i8* %s) #0 { +define i64 @strtol_not_const_str(ptr %s) #0 { ; CHECK-LABEL: @strtol_not_const_str( -; CHECK-NEXT: [[CALL:%.*]] = call i64 @strtol(i8* nocapture [[S:%.*]], i8** null, i32 10) +; CHECK-NEXT: [[CALL:%.*]] = call i64 @strtol(ptr nocapture [[S:%.*]], ptr null, i32 10) ; CHECK-NEXT: ret i64 [[CALL]] ; - %call = call i64 @strtol(i8* %s, i8** null, i32 10) #3 + %call = call i64 @strtol(ptr %s, ptr null, i32 10) #3 ret i64 %call } -define i32 @atoi_not_const_str(i8* %s) #0 { +define i32 @atoi_not_const_str(ptr %s) #0 { ; CHECK-LABEL: @atoi_not_const_str( -; CHECK-NEXT: [[CALL:%.*]] = call i32 @atoi(i8* nocapture [[S:%.*]]) +; CHECK-NEXT: [[CALL:%.*]] = call i32 @atoi(ptr nocapture [[S:%.*]]) ; CHECK-NEXT: ret i32 [[CALL]] ; - %call = call i32 @atoi(i8* %s) #4 + %call = call i32 @atoi(ptr %s) #4 ret i32 %call } define i64 @strtol_not_const_base(i32 %b) #0 { ; CHECK-LABEL: @strtol_not_const_base( -; CHECK-NEXT: [[CALL:%.*]] = call i64 @strtol(i8* nocapture getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0), i8** null, i32 [[B:%.*]]) +; CHECK-NEXT: [[CALL:%.*]] = call i64 @strtol(ptr nocapture nonnull @.str, ptr null, i32 [[B:%.*]]) ; CHECK-NEXT: ret i64 [[CALL]] ; - %call = call i64 @strtol(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i8** null, i32 %b) #2 + %call = call i64 @strtol(ptr @.str, ptr null, i32 %b) #2 ret i64 %call } @@ -101,17 +101,17 @@ ; CHECK-LABEL: @strtol_long_int( ; CHECK-NEXT: ret i64 4294967296 ; - %call = call i64 @strtol(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.2, i32 0, i32 0), i8** null, i32 10) #3 + %call = call i64 @strtol(ptr @.str.2, ptr null, i32 10) #3 ret i64 %call } define i64 @strtol_big_overflow() #0 { ; CHECK-LABEL: @strtol_big_overflow( -; CHECK-NEXT: [[CALL:%.*]] = call i64 @strtol(i8* nocapture getelementptr inbounds ([24 x i8], [24 x i8]* @.str.3, i64 0, i64 0), i8** null, i32 10) +; CHECK-NEXT: [[CALL:%.*]] = call i64 @strtol(ptr nocapture nonnull @.str.3, ptr null, i32 10) ; CHECK-NEXT: ret i64 [[CALL]] ; - %call = call i64 @strtol(i8* nocapture getelementptr inbounds ([24 x i8], [24 x i8]* @.str.3, i64 0, i64 0), i8** null, i32 10) #2 + %call = call i64 @strtol(ptr nocapture @.str.3, ptr null, i32 10) #2 ret i64 %call } @@ -120,7 +120,7 @@ ; CHECK-NEXT: ret i64 499496729 ; ; CHECK-NEXT - %call = call i64 @atol(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.6, i32 0, i32 0)) #4 + %call = call i64 @atol(ptr @.str.6) #4 ret i64 %call } @@ -128,7 +128,7 @@ ; CHECK-LABEL: @atoll_test( ; CHECK-NEXT: ret i64 4994967295 ; - %call = call i64 @atoll(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.5, i32 0, i32 0)) #3 + %call = call i64 @atoll(ptr @.str.5) #3 ret i64 %call } @@ -137,6 +137,6 @@ ; CHECK-NEXT: ret i64 4994967295 ; ; CHECK-NEXT - %call = call i64 @strtoll(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.7, i32 0, i32 0), i8** null, i32 10) #5 + %call = call i64 @strtoll(ptr @.str.7, ptr null, i32 10) #5 ret i64 %call } diff --git a/llvm/test/Transforms/InstCombine/str-int-3.ll b/llvm/test/Transforms/InstCombine/str-int-3.ll --- a/llvm/test/Transforms/InstCombine/str-int-3.ll +++ b/llvm/test/Transforms/InstCombine/str-int-3.ll @@ -66,8 +66,13 @@ define void @fold_atoi_offset_out_of_bounds(ptr %pi) { ; CHECK-LABEL: @fold_atoi_offset_out_of_bounds( -; TODO: Check folding. +; CHECK-NEXT: [[IA_0_0_32:%.*]] = call i32 @atoi(ptr nocapture getelementptr inbounds ([2 x %struct.A], ptr @a, i64 1, i64 0, i32 0, i64 0)) +; CHECK-NEXT: store i32 [[IA_0_0_32]], ptr [[PI:%.*]], align 4 +; CHECK-NEXT: [[IA_0_0_33:%.*]] = call i32 @atoi(ptr nocapture getelementptr ([2 x %struct.A], ptr @a, i64 1, i64 0, i32 0, i64 1)) +; CHECK-NEXT: store i32 [[IA_0_0_33]], ptr [[PI]], align 4 +; CHECK-NEXT: ret void ; +; TODO: Check folding. ; Fold atoi((const char*)a + sizeof a) to zero. %ia_0_0_32 = call i32 @atoi(ptr getelementptr inbounds ([2 x %struct.A], ptr @a, i64 1, i64 0, i32 0, i64 0)) store i32 %ia_0_0_32, ptr %pi diff --git a/llvm/test/Transforms/InstCombine/str-int-4.ll b/llvm/test/Transforms/InstCombine/str-int-4.ll --- a/llvm/test/Transforms/InstCombine/str-int-4.ll +++ b/llvm/test/Transforms/InstCombine/str-int-4.ll @@ -4,8 +4,8 @@ ; ; RUN: opt < %s -passes=instcombine -S | FileCheck %s -declare i32 @strtol(i8*, i8**, i32) -declare i64 @strtoll(i8*, i8**, i32) +declare i32 @strtol(ptr, ptr, i32) +declare i64 @strtoll(ptr, ptr, i32) ; All POSIX whitespace characters. @@ -35,120 +35,108 @@ @x32max = constant [12 x i8] c" 0x7fffffff\00" @i32max_p1 = constant [12 x i8] c" 2147483648\00" -@endptr = external global i8* +@endptr = external global ptr ; Exercise folding calls to 32-bit strtol. -define void @fold_strtol(i32* %ps) { +define void @fold_strtol(ptr %ps) { ; CHECK-LABEL: @fold_strtol( -; CHECK-NEXT: store i8* getelementptr inbounds ([11 x i8], [11 x i8]* @ws_im123, i64 0, i64 10), i8** @endptr, align 8 -; CHECK-NEXT: store i32 -123, i32* [[PS:%.*]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([11 x i8], [11 x i8]* @ws_ip234, i64 0, i64 10), i8** @endptr, align 8 -; CHECK-NEXT: [[PS1:%.*]] = getelementptr i32, i32* [[PS]], i64 1 -; CHECK-NEXT: store i32 234, i32* [[PS1]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([3 x i8], [3 x i8]* @i0, i64 0, i64 2), i8** @endptr, align 8 -; CHECK-NEXT: [[PS2:%.*]] = getelementptr i32, i32* [[PS]], i64 2 -; CHECK-NEXT: store i32 0, i32* [[PS2]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([3 x i8], [3 x i8]* @i9, i64 0, i64 2), i8** @endptr, align 8 -; CHECK-NEXT: [[PS3:%.*]] = getelementptr i32, i32* [[PS]], i64 3 -; CHECK-NEXT: store i32 9, i32* [[PS3]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([3 x i8], [3 x i8]* @ia, i64 0, i64 2), i8** @endptr, align 8 -; CHECK-NEXT: [[PS4:%.*]] = getelementptr i32, i32* [[PS]], i64 4 -; CHECK-NEXT: store i32 10, i32* [[PS4]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([7 x i8], [7 x i8]* @i19azAZ, i64 0, i64 6), i8** @endptr, align 8 -; CHECK-NEXT: [[PS5:%.*]] = getelementptr i32, i32* [[PS]], i64 5 -; CHECK-NEXT: store i32 76095035, i32* [[PS5]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([13 x i8], [13 x i8]* @i32min, i64 0, i64 12), i8** @endptr, align 8 -; CHECK-NEXT: [[PS6:%.*]] = getelementptr i32, i32* [[PS]], i64 6 -; CHECK-NEXT: store i32 -2147483648, i32* [[PS6]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([15 x i8], [15 x i8]* @mo32min, i64 0, i64 14), i8** @endptr, align 8 -; CHECK-NEXT: [[PS7:%.*]] = getelementptr i32, i32* [[PS]], i64 7 -; CHECK-NEXT: store i32 -2147483648, i32* [[PS7]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([13 x i8], [13 x i8]* @mx32min, i64 0, i64 12), i8** @endptr, align 8 -; CHECK-NEXT: [[PS8:%.*]] = getelementptr i32, i32* [[PS]], i64 8 -; CHECK-NEXT: store i32 -2147483648, i32* [[PS8]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([13 x i8], [13 x i8]* @mx32min, i64 0, i64 12), i8** @endptr, align 8 -; CHECK-NEXT: [[PS9:%.*]] = getelementptr i32, i32* [[PS]], i64 9 -; CHECK-NEXT: store i32 -2147483648, i32* [[PS9]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([12 x i8], [12 x i8]* @i32max, i64 0, i64 11), i8** @endptr, align 8 -; CHECK-NEXT: [[PS10:%.*]] = getelementptr i32, i32* [[PS]], i64 10 -; CHECK-NEXT: store i32 2147483647, i32* [[PS10]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([12 x i8], [12 x i8]* @x32max, i64 0, i64 11), i8** @endptr, align 8 -; CHECK-NEXT: [[PS11:%.*]] = getelementptr i32, i32* [[PS]], i64 11 -; CHECK-NEXT: store i32 2147483647, i32* [[PS11]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([11 x i8], ptr @ws_im123, i64 0, i64 10), ptr @endptr, align 8 +; CHECK-NEXT: store i32 -123, ptr [[PS:%.*]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([11 x i8], ptr @ws_ip234, i64 0, i64 10), ptr @endptr, align 8 +; CHECK-NEXT: [[PS1:%.*]] = getelementptr i32, ptr [[PS]], i64 1 +; CHECK-NEXT: store i32 234, ptr [[PS1]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([3 x i8], ptr @i0, i64 0, i64 2), ptr @endptr, align 8 +; CHECK-NEXT: [[PS2:%.*]] = getelementptr i32, ptr [[PS]], i64 2 +; CHECK-NEXT: store i32 0, ptr [[PS2]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([3 x i8], ptr @i9, i64 0, i64 2), ptr @endptr, align 8 +; CHECK-NEXT: [[PS3:%.*]] = getelementptr i32, ptr [[PS]], i64 3 +; CHECK-NEXT: store i32 9, ptr [[PS3]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([3 x i8], ptr @ia, i64 0, i64 2), ptr @endptr, align 8 +; CHECK-NEXT: [[PS4:%.*]] = getelementptr i32, ptr [[PS]], i64 4 +; CHECK-NEXT: store i32 10, ptr [[PS4]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([7 x i8], ptr @i19azAZ, i64 0, i64 6), ptr @endptr, align 8 +; CHECK-NEXT: [[PS5:%.*]] = getelementptr i32, ptr [[PS]], i64 5 +; CHECK-NEXT: store i32 76095035, ptr [[PS5]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([13 x i8], ptr @i32min, i64 0, i64 12), ptr @endptr, align 8 +; CHECK-NEXT: [[PS6:%.*]] = getelementptr i32, ptr [[PS]], i64 6 +; CHECK-NEXT: store i32 -2147483648, ptr [[PS6]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([15 x i8], ptr @mo32min, i64 0, i64 14), ptr @endptr, align 8 +; CHECK-NEXT: [[PS7:%.*]] = getelementptr i32, ptr [[PS]], i64 7 +; CHECK-NEXT: store i32 -2147483648, ptr [[PS7]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([13 x i8], ptr @mx32min, i64 0, i64 12), ptr @endptr, align 8 +; CHECK-NEXT: [[PS8:%.*]] = getelementptr i32, ptr [[PS]], i64 8 +; CHECK-NEXT: store i32 -2147483648, ptr [[PS8]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([13 x i8], ptr @mx32min, i64 0, i64 12), ptr @endptr, align 8 +; CHECK-NEXT: [[PS9:%.*]] = getelementptr i32, ptr [[PS]], i64 9 +; CHECK-NEXT: store i32 -2147483648, ptr [[PS9]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([12 x i8], ptr @i32max, i64 0, i64 11), ptr @endptr, align 8 +; CHECK-NEXT: [[PS10:%.*]] = getelementptr i32, ptr [[PS]], i64 10 +; CHECK-NEXT: store i32 2147483647, ptr [[PS10]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([12 x i8], ptr @x32max, i64 0, i64 11), ptr @endptr, align 8 +; CHECK-NEXT: [[PS11:%.*]] = getelementptr i32, ptr [[PS]], i64 11 +; CHECK-NEXT: store i32 2147483647, ptr [[PS11]], align 4 ; CHECK-NEXT: ret void ; ; Fold a valid sequence with leading POSIX whitespace and a minus to -123. - %pwsm123 = getelementptr [11 x i8], [11 x i8]* @ws_im123, i32 0, i32 0 - %im123 = call i32 @strtol(i8* %pwsm123, i8** @endptr, i32 10) - %ps0 = getelementptr i32, i32* %ps, i32 0 - store i32 %im123, i32* %ps0 + %im123 = call i32 @strtol(ptr @ws_im123, ptr @endptr, i32 10) + store i32 %im123, ptr %ps ; Fold a valid sequence with leading POSIX whitespace and a plus to +234. - %pwsp234 = getelementptr [11 x i8], [11 x i8]* @ws_ip234, i32 0, i32 0 - %ip234 = call i32 @strtol(i8* %pwsp234, i8** @endptr, i32 10) - %ps1 = getelementptr i32, i32* %ps, i32 1 - store i32 %ip234, i32* %ps1 + %ip234 = call i32 @strtol(ptr @ws_ip234, ptr @endptr, i32 10) + %ps1 = getelementptr i32, ptr %ps, i32 1 + store i32 %ip234, ptr %ps1 ; Fold " 0" in base 0 to verify correct base autodetection. - %psi0 = getelementptr [3 x i8], [3 x i8]* @i0, i32 0, i32 0 - %i0 = call i32 @strtol(i8* %psi0, i8** @endptr, i32 0) - %ps2 = getelementptr i32, i32* %ps, i32 2 - store i32 %i0, i32* %ps2 + %i0 = call i32 @strtol(ptr @i0, ptr @endptr, i32 0) + %ps2 = getelementptr i32, ptr %ps, i32 2 + store i32 %i0, ptr %ps2 ; Fold " 9" in base 0 to verify correct base autodetection. - %psi9 = getelementptr [3 x i8], [3 x i8]* @i9, i32 0, i32 0 - %i9 = call i32 @strtol(i8* %psi9, i8** @endptr, i32 0) - %ps3 = getelementptr i32, i32* %ps, i32 3 - store i32 %i9, i32* %ps3 + %i9 = call i32 @strtol(ptr @i9, ptr @endptr, i32 0) + %ps3 = getelementptr i32, ptr %ps, i32 3 + store i32 %i9, ptr %ps3 ; Fold " a" in base 16 to 10. - %psia = getelementptr [3 x i8], [3 x i8]* @ia, i32 0, i32 0 - %ia = call i32 @strtol(i8* %psia, i8** @endptr, i32 16) - %ps4 = getelementptr i32, i32* %ps, i32 4 - store i32 %ia, i32* %ps4 + %ia = call i32 @strtol(ptr @ia, ptr @endptr, i32 16) + %ps4 = getelementptr i32, ptr %ps, i32 4 + store i32 %ia, ptr %ps4 ; Fold "19azAZ" in base 36 to 76095035. - %psi19azAZ = getelementptr [7 x i8], [7 x i8]* @i19azAZ, i32 0, i32 0 - %i19azAZ = call i32 @strtol(i8* %psi19azAZ, i8** @endptr, i32 36) - %ps5 = getelementptr i32, i32* %ps, i32 5 - store i32 %i19azAZ, i32* %ps5 + %i19azAZ = call i32 @strtol(ptr @i19azAZ, ptr @endptr, i32 36) + %ps5 = getelementptr i32, ptr %ps, i32 5 + store i32 %i19azAZ, ptr %ps5 ; Fold INT32_MIN. - %psmin = getelementptr [13 x i8], [13 x i8]* @i32min, i32 0, i32 0 - %min = call i32 @strtol(i8* %psmin, i8** @endptr, i32 10) - %ps6 = getelementptr i32, i32* %ps, i32 6 - store i32 %min, i32* %ps6 + %min = call i32 @strtol(ptr @i32min, ptr @endptr, i32 10) + %ps6 = getelementptr i32, ptr %ps, i32 6 + store i32 %min, ptr %ps6 ; Fold -INT32_MIN in octal. - %psmo32min = getelementptr [15 x i8], [15 x i8]* @mo32min, i32 0, i32 0 - %mo32min = call i32 @strtol(i8* %psmo32min, i8** @endptr, i32 0) - %ps7 = getelementptr i32, i32* %ps, i32 7 - store i32 %mo32min, i32* %ps7 + %mo32min = call i32 @strtol(ptr @mo32min, ptr @endptr, i32 0) + %ps7 = getelementptr i32, ptr %ps, i32 7 + store i32 %mo32min, ptr %ps7 ; Fold -INT32_MIN in hex and base 0. - %psmx32min = getelementptr [13 x i8], [13 x i8]* @mx32min, i32 0, i32 0 - %mx32min_0 = call i32 @strtol(i8* %psmx32min, i8** @endptr, i32 0) - %ps8 = getelementptr i32, i32* %ps, i32 8 - store i32 %mx32min_0, i32* %ps8 + %mx32min_0 = call i32 @strtol(ptr @mx32min, ptr @endptr, i32 0) + %ps8 = getelementptr i32, ptr %ps, i32 8 + store i32 %mx32min_0, ptr %ps8 ; Fold -INT32_MIN in hex and base 16. - %mx32min_16 = call i32 @strtol(i8* %psmx32min, i8** @endptr, i32 16) - %ps9 = getelementptr i32, i32* %ps, i32 9 - store i32 %mx32min_16, i32* %ps9 + %mx32min_16 = call i32 @strtol(ptr @mx32min, ptr @endptr, i32 16) + %ps9 = getelementptr i32, ptr %ps, i32 9 + store i32 %mx32min_16, ptr %ps9 ; Fold INT32_MAX. - %psmax = getelementptr [12 x i8], [12 x i8]* @i32max, i32 0, i32 0 - %max = call i32 @strtol(i8* %psmax, i8** @endptr, i32 10) - %ps10 = getelementptr i32, i32* %ps, i32 10 - store i32 %max, i32* %ps10 + %max = call i32 @strtol(ptr @i32max, ptr @endptr, i32 10) + %ps10 = getelementptr i32, ptr %ps, i32 10 + store i32 %max, ptr %ps10 ; Fold INT32_MAX in hex. - %psxmax = getelementptr [12 x i8], [12 x i8]* @x32max, i32 0, i32 0 - %xmax = call i32 @strtol(i8* %psxmax, i8** @endptr, i32 0) - %ps11 = getelementptr i32, i32* %ps, i32 11 - store i32 %xmax, i32* %ps11 + %xmax = call i32 @strtol(ptr @x32max, ptr @endptr, i32 0) + %ps11 = getelementptr i32, ptr %ps, i32 11 + store i32 %xmax, ptr %ps11 ret void } @@ -156,143 +144,130 @@ ; Exercise not folding calls to 32-bit strtol. -define void @call_strtol(i32* %ps) { +define void @call_strtol(ptr %ps) { ; CHECK-LABEL: @call_strtol( -; CHECK-NEXT: [[MINM1:%.*]] = call i32 @strtol(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @i32min_m1, i64 0, i64 0), i8** nonnull @endptr, i32 10) -; CHECK-NEXT: store i32 [[MINM1]], i32* [[PS:%.*]], align 4 -; CHECK-NEXT: [[MAXP1:%.*]] = call i32 @strtol(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @i32max_p1, i64 0, i64 0), i8** nonnull @endptr, i32 10) -; CHECK-NEXT: [[PS1:%.*]] = getelementptr i32, i32* [[PS]], i64 1 -; CHECK-NEXT: store i32 [[MAXP1]], i32* [[PS1]], align 4 -; CHECK-NEXT: [[IPLUS:%.*]] = call i32 @strtol(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @wsplus, i64 0, i64 0), i8** nonnull @endptr, i32 0) -; CHECK-NEXT: [[PS2:%.*]] = getelementptr i32, i32* [[PS]], i64 2 -; CHECK-NEXT: store i32 [[IPLUS]], i32* [[PS2]], align 4 -; CHECK-NEXT: [[IA:%.*]] = call i32 @strtol(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @ia, i64 0, i64 0), i8** nonnull @endptr, i32 0) -; CHECK-NEXT: [[PS3:%.*]] = getelementptr i32, i32* [[PS]], i64 3 -; CHECK-NEXT: store i32 [[IA]], i32* [[PS3]], align 4 -; CHECK-NEXT: [[I8:%.*]] = call i32 @strtol(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @i8, i64 0, i64 0), i8** nonnull @endptr, i32 8) -; CHECK-NEXT: [[PS4:%.*]] = getelementptr i32, i32* [[PS]], i64 4 -; CHECK-NEXT: store i32 [[I8]], i32* [[PS4]], align 4 -; CHECK-NEXT: [[I0X:%.*]] = call i32 @strtol(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @x0x, i64 0, i64 0), i8** nonnull @endptr, i32 0) -; CHECK-NEXT: [[PS5:%.*]] = getelementptr i32, i32* [[PS]], i64 5 -; CHECK-NEXT: store i32 [[I0X]], i32* [[PS5]], align 4 -; CHECK-NEXT: [[IWSPWS0:%.*]] = call i32 @strtol(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @wsplusws0, i64 0, i64 0), i8** nonnull @endptr, i32 0) -; CHECK-NEXT: [[PS6:%.*]] = getelementptr i32, i32* [[PS]], i64 6 -; CHECK-NEXT: store i32 [[IWSPWS0]], i32* [[PS6]], align 4 -; CHECK-NEXT: [[I19AZAZ:%.*]] = call i32 @strtol(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @i19azAZ, i64 0, i64 0), i8** nonnull @endptr, i32 35) -; CHECK-NEXT: [[PS7:%.*]] = getelementptr i32, i32* [[PS]], i64 7 -; CHECK-NEXT: store i32 [[I19AZAZ]], i32* [[PS7]], align 4 -; CHECK-NEXT: [[O32MIN:%.*]] = call i32 @strtol(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @o32min, i64 0, i64 0), i8** nonnull @endptr, i32 0) -; CHECK-NEXT: [[PS8:%.*]] = getelementptr i32, i32* [[PS]], i64 8 -; CHECK-NEXT: store i32 [[O32MIN]], i32* [[PS8]], align 4 -; CHECK-NEXT: [[X32MIN:%.*]] = call i32 @strtol(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @x32min, i64 0, i64 0), i8** nonnull @endptr, i32 0) -; CHECK-NEXT: [[PS9:%.*]] = getelementptr i32, i32* [[PS]], i64 9 -; CHECK-NEXT: store i32 [[X32MIN]], i32* [[PS9]], align 4 -; CHECK-NEXT: [[X32MIN_10:%.*]] = call i32 @strtol(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @x32min, i64 0, i64 0), i8** nonnull @endptr, i32 10) -; CHECK-NEXT: [[PS10:%.*]] = getelementptr i32, i32* [[PS]], i64 10 -; CHECK-NEXT: store i32 [[X32MIN_10]], i32* [[PS10]], align 4 -; CHECK-NEXT: [[NWS:%.*]] = call i32 @strtol(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @ws, i64 0, i64 0), i8** nonnull @endptr, i32 10) -; CHECK-NEXT: [[PS11:%.*]] = getelementptr i32, i32* [[PS]], i64 11 -; CHECK-NEXT: store i32 [[NWS]], i32* [[PS11]], align 4 -; CHECK-NEXT: [[NWSP6:%.*]] = call i32 @strtol(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @ws, i64 0, i64 6), i8** nonnull @endptr, i32 10) -; CHECK-NEXT: [[PS12:%.*]] = getelementptr i32, i32* [[PS]], i64 12 -; CHECK-NEXT: store i32 [[NWSP6]], i32* [[PS12]], align 4 -; CHECK-NEXT: [[I0B1:%.*]] = call i32 @strtol(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @i0, i64 0, i64 0), i8** nonnull @endptr, i32 1) -; CHECK-NEXT: [[PS13:%.*]] = getelementptr i32, i32* [[PS]], i64 13 -; CHECK-NEXT: store i32 [[I0B1]], i32* [[PS13]], align 4 -; CHECK-NEXT: [[I0B256:%.*]] = call i32 @strtol(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @i0, i64 0, i64 0), i8** nonnull @endptr, i32 256) -; CHECK-NEXT: [[PS14:%.*]] = getelementptr i32, i32* [[PS]], i64 14 -; CHECK-NEXT: store i32 [[I0B256]], i32* [[PS14]], align 4 +; CHECK-NEXT: [[MINM1:%.*]] = call i32 @strtol(ptr nonnull @i32min_m1, ptr nonnull @endptr, i32 10) +; CHECK-NEXT: store i32 [[MINM1]], ptr [[PS:%.*]], align 4 +; CHECK-NEXT: [[MAXP1:%.*]] = call i32 @strtol(ptr nonnull @i32max_p1, ptr nonnull @endptr, i32 10) +; CHECK-NEXT: [[PS1:%.*]] = getelementptr i32, ptr [[PS]], i64 1 +; CHECK-NEXT: store i32 [[MAXP1]], ptr [[PS1]], align 4 +; CHECK-NEXT: [[IPLUS:%.*]] = call i32 @strtol(ptr nonnull @wsplus, ptr nonnull @endptr, i32 0) +; CHECK-NEXT: [[PS2:%.*]] = getelementptr i32, ptr [[PS]], i64 2 +; CHECK-NEXT: store i32 [[IPLUS]], ptr [[PS2]], align 4 +; CHECK-NEXT: [[IA:%.*]] = call i32 @strtol(ptr nonnull @ia, ptr nonnull @endptr, i32 0) +; CHECK-NEXT: [[PS3:%.*]] = getelementptr i32, ptr [[PS]], i64 3 +; CHECK-NEXT: store i32 [[IA]], ptr [[PS3]], align 4 +; CHECK-NEXT: [[I8:%.*]] = call i32 @strtol(ptr nonnull @i8, ptr nonnull @endptr, i32 8) +; CHECK-NEXT: [[PS4:%.*]] = getelementptr i32, ptr [[PS]], i64 4 +; CHECK-NEXT: store i32 [[I8]], ptr [[PS4]], align 4 +; CHECK-NEXT: [[I0X:%.*]] = call i32 @strtol(ptr nonnull @x0x, ptr nonnull @endptr, i32 0) +; CHECK-NEXT: [[PS5:%.*]] = getelementptr i32, ptr [[PS]], i64 5 +; CHECK-NEXT: store i32 [[I0X]], ptr [[PS5]], align 4 +; CHECK-NEXT: [[IWSPWS0:%.*]] = call i32 @strtol(ptr nonnull @wsplusws0, ptr nonnull @endptr, i32 0) +; CHECK-NEXT: [[PS6:%.*]] = getelementptr i32, ptr [[PS]], i64 6 +; CHECK-NEXT: store i32 [[IWSPWS0]], ptr [[PS6]], align 4 +; CHECK-NEXT: [[I19AZAZ:%.*]] = call i32 @strtol(ptr nonnull @i19azAZ, ptr nonnull @endptr, i32 35) +; CHECK-NEXT: [[PS7:%.*]] = getelementptr i32, ptr [[PS]], i64 7 +; CHECK-NEXT: store i32 [[I19AZAZ]], ptr [[PS7]], align 4 +; CHECK-NEXT: [[O32MIN:%.*]] = call i32 @strtol(ptr nonnull @o32min, ptr nonnull @endptr, i32 0) +; CHECK-NEXT: [[PS8:%.*]] = getelementptr i32, ptr [[PS]], i64 8 +; CHECK-NEXT: store i32 [[O32MIN]], ptr [[PS8]], align 4 +; CHECK-NEXT: [[X32MIN:%.*]] = call i32 @strtol(ptr nonnull @x32min, ptr nonnull @endptr, i32 0) +; CHECK-NEXT: [[PS9:%.*]] = getelementptr i32, ptr [[PS]], i64 9 +; CHECK-NEXT: store i32 [[X32MIN]], ptr [[PS9]], align 4 +; CHECK-NEXT: [[X32MIN_10:%.*]] = call i32 @strtol(ptr nonnull @x32min, ptr nonnull @endptr, i32 10) +; CHECK-NEXT: [[PS10:%.*]] = getelementptr i32, ptr [[PS]], i64 10 +; CHECK-NEXT: store i32 [[X32MIN_10]], ptr [[PS10]], align 4 +; CHECK-NEXT: [[NWS:%.*]] = call i32 @strtol(ptr nonnull @ws, ptr nonnull @endptr, i32 10) +; CHECK-NEXT: [[PS11:%.*]] = getelementptr i32, ptr [[PS]], i64 11 +; CHECK-NEXT: store i32 [[NWS]], ptr [[PS11]], align 4 +; CHECK-NEXT: [[NWSP6:%.*]] = call i32 @strtol(ptr getelementptr inbounds ([7 x i8], ptr @ws, i64 0, i64 6), ptr nonnull @endptr, i32 10) +; CHECK-NEXT: [[PS12:%.*]] = getelementptr i32, ptr [[PS]], i64 12 +; CHECK-NEXT: store i32 [[NWSP6]], ptr [[PS12]], align 4 +; CHECK-NEXT: [[I0B1:%.*]] = call i32 @strtol(ptr nonnull @i0, ptr nonnull @endptr, i32 1) +; CHECK-NEXT: [[PS13:%.*]] = getelementptr i32, ptr [[PS]], i64 13 +; CHECK-NEXT: store i32 [[I0B1]], ptr [[PS13]], align 4 +; CHECK-NEXT: [[I0B256:%.*]] = call i32 @strtol(ptr nonnull @i0, ptr nonnull @endptr, i32 256) +; CHECK-NEXT: [[PS14:%.*]] = getelementptr i32, ptr [[PS]], i64 14 +; CHECK-NEXT: store i32 [[I0B256]], ptr [[PS14]], align 4 ; CHECK-NEXT: ret void ; ; Do not fold the result of conversion that's less than INT32_MIN. - %psminm1 = getelementptr [13 x i8], [13 x i8]* @i32min_m1, i32 0, i32 0 - %minm1 = call i32 @strtol(i8* %psminm1, i8** @endptr, i32 10) - %ps0 = getelementptr i32, i32* %ps, i32 0 - store i32 %minm1, i32* %ps0 + %minm1 = call i32 @strtol(ptr @i32min_m1, ptr @endptr, i32 10) + store i32 %minm1, ptr %ps ; Do not fold the result of conversion that's greater than INT32_MAX. - %psmaxp1 = getelementptr [12 x i8], [12 x i8]* @i32max_p1, i32 0, i32 0 - %maxp1 = call i32 @strtol(i8* %psmaxp1, i8** @endptr, i32 10) - %ps1 = getelementptr i32, i32* %ps, i32 1 - store i32 %maxp1, i32* %ps1 + %maxp1 = call i32 @strtol(ptr @i32max_p1, ptr @endptr, i32 10) + %ps1 = getelementptr i32, ptr %ps, i32 1 + store i32 %maxp1, ptr %ps1 ; Do not fold " +". - %psplus = getelementptr [3 x i8], [3 x i8]* @wsplus, i32 0, i32 0 - %iplus = call i32 @strtol(i8* %psplus, i8** @endptr, i32 0) - %ps2 = getelementptr i32, i32* %ps, i32 2 - store i32 %iplus, i32* %ps2 + %iplus = call i32 @strtol(ptr @wsplus, ptr @endptr, i32 0) + %ps2 = getelementptr i32, ptr %ps, i32 2 + store i32 %iplus, ptr %ps2 ; Do not fold " a" in base 0. - %psia = getelementptr [3 x i8], [3 x i8]* @ia, i32 0, i32 0 - %ia = call i32 @strtol(i8* %psia, i8** @endptr, i32 0) - %ps3 = getelementptr i32, i32* %ps, i32 3 - store i32 %ia, i32* %ps3 + %ia = call i32 @strtol(ptr @ia, ptr @endptr, i32 0) + %ps3 = getelementptr i32, ptr %ps, i32 3 + store i32 %ia, ptr %ps3 ; Do not fold " 8" in base 8. - %psi8 = getelementptr [3 x i8], [3 x i8]* @i8, i32 0, i32 0 - %i8 = call i32 @strtol(i8* %psi8, i8** @endptr, i32 8) - %ps4 = getelementptr i32, i32* %ps, i32 4 - store i32 %i8, i32* %ps4 + %i8 = call i32 @strtol(ptr @i8, ptr @endptr, i32 8) + %ps4 = getelementptr i32, ptr %ps, i32 4 + store i32 %i8, ptr %ps4 ; Do not fold the "0x" alone in base 0 that some implementations (e.g., ; BSD and Darwin) set errno to EINVAL for. - %psx0x = getelementptr [3 x i8], [3 x i8]* @x0x, i32 0, i32 0 - %i0x = call i32 @strtol(i8* %psx0x, i8** @endptr, i32 0) - %ps5 = getelementptr i32, i32* %ps, i32 5 - store i32 %i0x, i32* %ps5 + %i0x = call i32 @strtol(ptr @x0x, ptr @endptr, i32 0) + %ps5 = getelementptr i32, ptr %ps, i32 5 + store i32 %i0x, ptr %ps5 ; Do not fold " + 0". - %pwspws0 = getelementptr [5 x i8], [5 x i8]* @wsplusws0, i32 0, i32 0 - %iwspws0 = call i32 @strtol(i8* %pwspws0, i8** @endptr, i32 0) - %ps6 = getelementptr i32, i32* %ps, i32 6 - store i32 %iwspws0, i32* %ps6 + %iwspws0 = call i32 @strtol(ptr @wsplusws0, ptr @endptr, i32 0) + %ps6 = getelementptr i32, ptr %ps, i32 6 + store i32 %iwspws0, ptr %ps6 ; Do not fold "19azAZ" in base 35. - %psi19azAZ = getelementptr [7 x i8], [7 x i8]* @i19azAZ, i32 0, i32 0 - %i19azAZ = call i32 @strtol(i8* %psi19azAZ, i8** @endptr, i32 35) - %ps7 = getelementptr i32, i32* %ps, i32 7 - store i32 %i19azAZ, i32* %ps7 + %i19azAZ = call i32 @strtol(ptr @i19azAZ, ptr @endptr, i32 35) + %ps7 = getelementptr i32, ptr %ps, i32 7 + store i32 %i19azAZ, ptr %ps7 ; Do not fold INT32_MIN in octal. - %pso32min = getelementptr [15 x i8], [15 x i8]* @o32min, i32 0, i32 0 - %o32min = call i32 @strtol(i8* %pso32min, i8** @endptr, i32 0) - %ps8 = getelementptr i32, i32* %ps, i32 8 - store i32 %o32min, i32* %ps8 + %o32min = call i32 @strtol(ptr @o32min, ptr @endptr, i32 0) + %ps8 = getelementptr i32, ptr %ps, i32 8 + store i32 %o32min, ptr %ps8 ; Do not fold INT32_MIN in hex. - %psx32min = getelementptr [13 x i8], [13 x i8]* @x32min, i32 0, i32 0 - %x32min = call i32 @strtol(i8* %psx32min, i8** @endptr, i32 0) - %ps9 = getelementptr i32, i32* %ps, i32 9 - store i32 %x32min, i32* %ps9 + %x32min = call i32 @strtol(ptr @x32min, ptr @endptr, i32 0) + %ps9 = getelementptr i32, ptr %ps, i32 9 + store i32 %x32min, ptr %ps9 ; Do not fold INT32_MIN in hex in base 10. - %x32min_10 = call i32 @strtol(i8* %psx32min, i8** @endptr, i32 10) - %ps10 = getelementptr i32, i32* %ps, i32 10 - store i32 %x32min_10, i32* %ps10 + %x32min_10 = call i32 @strtol(ptr @x32min, ptr @endptr, i32 10) + %ps10 = getelementptr i32, ptr %ps, i32 10 + store i32 %x32min_10, ptr %ps10 ; Do not fold a sequence consisting of just whitespace characters. - %psws = getelementptr [7 x i8], [7 x i8]* @ws, i32 0, i32 0 - %nws = call i32 @strtol(i8* %psws, i8** @endptr, i32 10) - %ps11 = getelementptr i32, i32* %ps, i32 11 - store i32 %nws, i32* %ps11 + %nws = call i32 @strtol(ptr @ws, ptr @endptr, i32 10) + %ps11 = getelementptr i32, ptr %ps, i32 11 + store i32 %nws, ptr %ps11 ; Do not fold an empty sequence. - %pswsp6 = getelementptr [7 x i8], [7 x i8]* @ws, i32 0, i32 6 - %nwsp6 = call i32 @strtol(i8* %pswsp6, i8** @endptr, i32 10) - %ps12 = getelementptr i32, i32* %ps, i32 12 - store i32 %nwsp6, i32* %ps12 + %pswsp6 = getelementptr [7 x i8], ptr @ws, i32 0, i32 6 + %nwsp6 = call i32 @strtol(ptr %pswsp6, ptr @endptr, i32 10) + %ps12 = getelementptr i32, ptr %ps, i32 12 + store i32 %nwsp6, ptr %ps12 ; Do not fold the invalid base 1. - %psi0 = getelementptr [3 x i8], [3 x i8]* @i0, i32 0, i32 0 - %i0b1 = call i32 @strtol(i8* %psi0, i8** @endptr, i32 1) - %ps13 = getelementptr i32, i32* %ps, i32 13 - store i32 %i0b1, i32* %ps13 + %i0b1 = call i32 @strtol(ptr @i0, ptr @endptr, i32 1) + %ps13 = getelementptr i32, ptr %ps, i32 13 + store i32 %i0b1, ptr %ps13 ; Do not fold the invalid base 256. - %i0b256 = call i32 @strtol(i8* %psi0, i8** @endptr, i32 256) - %ps14 = getelementptr i32, i32* %ps, i32 14 - store i32 %i0b256, i32* %ps14 + %i0b256 = call i32 @strtol(ptr @i0, ptr @endptr, i32 256) + %ps14 = getelementptr i32, ptr %ps, i32 14 + store i32 %i0b256, ptr %ps14 ret void } @@ -310,44 +285,39 @@ ; Exercise folding calls to the 64-bit strtoll. -define void @fold_strtoll(i64* %ps) { +define void @fold_strtoll(ptr %ps) { ; CHECK-LABEL: @fold_strtoll( -; CHECK-NEXT: store i8* getelementptr inbounds ([11 x i8], [11 x i8]* @ws_im123, i64 0, i64 10), i8** @endptr, align 8 -; CHECK-NEXT: store i64 -123, i64* [[PS:%.*]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([11 x i8], [11 x i8]* @ws_ip234, i64 0, i64 10), i8** @endptr, align 8 -; CHECK-NEXT: [[PS1:%.*]] = getelementptr i64, i64* [[PS]], i64 1 -; CHECK-NEXT: store i64 234, i64* [[PS1]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([22 x i8], [22 x i8]* @i64min, i64 0, i64 21), i8** @endptr, align 8 -; CHECK-NEXT: [[PS2:%.*]] = getelementptr i64, i64* [[PS]], i64 2 -; CHECK-NEXT: store i64 -9223372036854775808, i64* [[PS2]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([21 x i8], [21 x i8]* @i64max, i64 0, i64 20), i8** @endptr, align 8 -; CHECK-NEXT: [[PS3:%.*]] = getelementptr i64, i64* [[PS]], i64 3 -; CHECK-NEXT: store i64 9223372036854775807, i64* [[PS3]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([11 x i8], ptr @ws_im123, i64 0, i64 10), ptr @endptr, align 8 +; CHECK-NEXT: store i64 -123, ptr [[PS:%.*]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([11 x i8], ptr @ws_ip234, i64 0, i64 10), ptr @endptr, align 8 +; CHECK-NEXT: [[PS1:%.*]] = getelementptr i64, ptr [[PS]], i64 1 +; CHECK-NEXT: store i64 234, ptr [[PS1]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([22 x i8], ptr @i64min, i64 0, i64 21), ptr @endptr, align 8 +; CHECK-NEXT: [[PS2:%.*]] = getelementptr i64, ptr [[PS]], i64 2 +; CHECK-NEXT: store i64 -9223372036854775808, ptr [[PS2]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([21 x i8], ptr @i64max, i64 0, i64 20), ptr @endptr, align 8 +; CHECK-NEXT: [[PS3:%.*]] = getelementptr i64, ptr [[PS]], i64 3 +; CHECK-NEXT: store i64 9223372036854775807, ptr [[PS3]], align 4 ; CHECK-NEXT: ret void ; ; Fold a valid sequence with leading POSIX whitespace and a minus to -123. - %pwsm123 = getelementptr [11 x i8], [11 x i8]* @ws_im123, i32 0, i32 0 - %im123 = call i64 @strtoll(i8* %pwsm123, i8** @endptr, i32 10) - %ps0 = getelementptr i64, i64* %ps, i32 0 - store i64 %im123, i64* %ps0 + %im123 = call i64 @strtoll(ptr @ws_im123, ptr @endptr, i32 10) + store i64 %im123, ptr %ps ; Fold a valid sequence with leading POSIX whitespace and a plus to +234. - %pwsp234 = getelementptr [11 x i8], [11 x i8]* @ws_ip234, i32 0, i32 0 - %ip234 = call i64 @strtoll(i8* %pwsp234, i8** @endptr, i32 10) - %ps1 = getelementptr i64, i64* %ps, i32 1 - store i64 %ip234, i64* %ps1 + %ip234 = call i64 @strtoll(ptr @ws_ip234, ptr @endptr, i32 10) + %ps1 = getelementptr i64, ptr %ps, i32 1 + store i64 %ip234, ptr %ps1 ; Fold INT64_MIN. - %psmin = getelementptr [22 x i8], [22 x i8]* @i64min, i32 0, i32 0 - %min = call i64 @strtoll(i8* %psmin, i8** @endptr, i32 10) - %ps2 = getelementptr i64, i64* %ps, i32 2 - store i64 %min, i64* %ps2 + %min = call i64 @strtoll(ptr @i64min, ptr @endptr, i32 10) + %ps2 = getelementptr i64, ptr %ps, i32 2 + store i64 %min, ptr %ps2 ; Fold INT64_MAX. - %psmax = getelementptr [21 x i8], [21 x i8]* @i64max, i32 0, i32 0 - %max = call i64 @strtoll(i8* %psmax, i8** @endptr, i32 10) - %ps3 = getelementptr i64, i64* %ps, i32 3 - store i64 %max, i64* %ps3 + %max = call i64 @strtoll(ptr @i64max, ptr @endptr, i32 10) + %ps3 = getelementptr i64, ptr %ps, i32 3 + store i64 %max, ptr %ps3 ret void } @@ -355,44 +325,40 @@ ; Exercise not folding calls to the 64-bit strtoll. -define void @call_strtoll(i64* %ps) { +define void @call_strtoll(ptr %ps) { ; CHECK-LABEL: @call_strtoll( -; CHECK-NEXT: [[MINM1:%.*]] = call i64 @strtoll(i8* getelementptr inbounds ([22 x i8], [22 x i8]* @i64min_m1, i64 0, i64 0), i8** nonnull @endptr, i32 10) -; CHECK-NEXT: store i64 [[MINM1]], i64* [[PS:%.*]], align 4 -; CHECK-NEXT: [[MAXP1:%.*]] = call i64 @strtoll(i8* getelementptr inbounds ([21 x i8], [21 x i8]* @i64max_p1, i64 0, i64 0), i8** nonnull @endptr, i32 10) -; CHECK-NEXT: [[PS1:%.*]] = getelementptr i64, i64* [[PS]], i64 1 -; CHECK-NEXT: store i64 [[MAXP1]], i64* [[PS1]], align 4 -; CHECK-NEXT: [[NWS:%.*]] = call i64 @strtoll(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @ws, i64 0, i64 0), i8** nonnull @endptr, i32 10) -; CHECK-NEXT: [[PS2:%.*]] = getelementptr i64, i64* [[PS]], i64 2 -; CHECK-NEXT: store i64 [[NWS]], i64* [[PS2]], align 4 -; CHECK-NEXT: [[NWSP6:%.*]] = call i64 @strtoll(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @ws, i64 0, i64 6), i8** nonnull @endptr, i32 10) -; CHECK-NEXT: [[PS3:%.*]] = getelementptr i64, i64* [[PS]], i64 3 -; CHECK-NEXT: store i64 [[NWSP6]], i64* [[PS3]], align 4 +; CHECK-NEXT: [[MINM1:%.*]] = call i64 @strtoll(ptr nonnull @i64min_m1, ptr nonnull @endptr, i32 10) +; CHECK-NEXT: store i64 [[MINM1]], ptr [[PS:%.*]], align 4 +; CHECK-NEXT: [[MAXP1:%.*]] = call i64 @strtoll(ptr nonnull @i64max_p1, ptr nonnull @endptr, i32 10) +; CHECK-NEXT: [[PS1:%.*]] = getelementptr i64, ptr [[PS]], i64 1 +; CHECK-NEXT: store i64 [[MAXP1]], ptr [[PS1]], align 4 +; CHECK-NEXT: [[NWS:%.*]] = call i64 @strtoll(ptr nonnull @ws, ptr nonnull @endptr, i32 10) +; CHECK-NEXT: [[PS2:%.*]] = getelementptr i64, ptr [[PS]], i64 2 +; CHECK-NEXT: store i64 [[NWS]], ptr [[PS2]], align 4 +; CHECK-NEXT: [[NWSP6:%.*]] = call i64 @strtoll(ptr getelementptr inbounds ([7 x i8], ptr @ws, i64 0, i64 6), ptr nonnull @endptr, i32 10) +; CHECK-NEXT: [[PS3:%.*]] = getelementptr i64, ptr [[PS]], i64 3 +; CHECK-NEXT: store i64 [[NWSP6]], ptr [[PS3]], align 4 ; CHECK-NEXT: ret void ; ; Do not fold the result of conversion that's less than INT64_MIN. - %psminm1 = getelementptr [22 x i8], [22 x i8]* @i64min_m1, i32 0, i32 0 - %minm1 = call i64 @strtoll(i8* %psminm1, i8** @endptr, i32 10) - %ps0 = getelementptr i64, i64* %ps, i32 0 - store i64 %minm1, i64* %ps0 + %minm1 = call i64 @strtoll(ptr @i64min_m1, ptr @endptr, i32 10) + store i64 %minm1, ptr %ps ; Do not fold the result of conversion that's greater than INT64_MAX. - %psmaxp1 = getelementptr [21 x i8], [21 x i8]* @i64max_p1, i32 0, i32 0 - %maxp1 = call i64 @strtoll(i8* %psmaxp1, i8** @endptr, i32 10) - %ps1 = getelementptr i64, i64* %ps, i32 1 - store i64 %maxp1, i64* %ps1 + %maxp1 = call i64 @strtoll(ptr @i64max_p1, ptr @endptr, i32 10) + %ps1 = getelementptr i64, ptr %ps, i32 1 + store i64 %maxp1, ptr %ps1 ; Do not fold a sequence consisting of just whitespace characters. - %psws = getelementptr [7 x i8], [7 x i8]* @ws, i32 0, i32 0 - %nws = call i64 @strtoll(i8* %psws, i8** @endptr, i32 10) - %ps2 = getelementptr i64, i64* %ps, i32 2 - store i64 %nws, i64* %ps2 + %nws = call i64 @strtoll(ptr @ws, ptr @endptr, i32 10) + %ps2 = getelementptr i64, ptr %ps, i32 2 + store i64 %nws, ptr %ps2 ; Do not fold an empty sequence. - %pswsp6 = getelementptr [7 x i8], [7 x i8]* @ws, i32 0, i32 6 - %nwsp6 = call i64 @strtoll(i8* %pswsp6, i8** @endptr, i32 10) - %ps3 = getelementptr i64, i64* %ps, i32 3 - store i64 %nwsp6, i64* %ps3 + %pswsp6 = getelementptr [7 x i8], ptr @ws, i32 0, i32 6 + %nwsp6 = call i64 @strtoll(ptr %pswsp6, ptr @endptr, i32 10) + %ps3 = getelementptr i64, ptr %ps, i32 3 + store i64 %nwsp6, ptr %ps3 ret void } @@ -404,33 +370,32 @@ ; as part of the leading digits, such as "123 456" is interepreted as ; 123456 in the French locale). -define void @call_strtol_trailing_space(i32* %ps) { +define void @call_strtol_trailing_space(ptr %ps) { ; CHECK-LABEL: @call_strtol_trailing_space( -; CHECK-NEXT: [[N1:%.*]] = call i32 @strtol(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @i_1_2_3_, i64 0, i64 0), i8** nonnull @endptr, i32 10) -; CHECK-NEXT: [[PS1:%.*]] = getelementptr i32, i32* [[PS:%.*]], i64 1 -; CHECK-NEXT: store i32 [[N1]], i32* [[PS1]], align 4 -; CHECK-NEXT: [[N2:%.*]] = call i32 @strtol(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @i_1_2_3_, i64 0, i64 2), i8** nonnull @endptr, i32 10) -; CHECK-NEXT: [[PS2:%.*]] = getelementptr i32, i32* [[PS]], i64 2 -; CHECK-NEXT: store i32 [[N2]], i32* [[PS2]], align 4 -; CHECK-NEXT: [[N3:%.*]] = call i32 @strtol(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @i_1_2_3_, i64 0, i64 4), i8** nonnull @endptr, i32 10) -; CHECK-NEXT: [[PS3:%.*]] = getelementptr i32, i32* [[PS]], i64 3 -; CHECK-NEXT: store i32 [[N3]], i32* [[PS3]], align 4 +; CHECK-NEXT: [[N1:%.*]] = call i32 @strtol(ptr nonnull @i_1_2_3_, ptr nonnull @endptr, i32 10) +; CHECK-NEXT: [[PS1:%.*]] = getelementptr i32, ptr [[PS:%.*]], i64 1 +; CHECK-NEXT: store i32 [[N1]], ptr [[PS1]], align 4 +; CHECK-NEXT: [[N2:%.*]] = call i32 @strtol(ptr getelementptr inbounds ([9 x i8], ptr @i_1_2_3_, i64 0, i64 2), ptr nonnull @endptr, i32 10) +; CHECK-NEXT: [[PS2:%.*]] = getelementptr i32, ptr [[PS]], i64 2 +; CHECK-NEXT: store i32 [[N2]], ptr [[PS2]], align 4 +; CHECK-NEXT: [[N3:%.*]] = call i32 @strtol(ptr getelementptr inbounds ([9 x i8], ptr @i_1_2_3_, i64 0, i64 4), ptr nonnull @endptr, i32 10) +; CHECK-NEXT: [[PS3:%.*]] = getelementptr i32, ptr [[PS]], i64 3 +; CHECK-NEXT: store i32 [[N3]], ptr [[PS3]], align 4 ; CHECK-NEXT: ret void ; - %p1 = getelementptr [9 x i8], [9 x i8]* @i_1_2_3_, i32 0, i32 0 - %n1 = call i32 @strtol(i8* %p1, i8** @endptr, i32 10) - %ps1 = getelementptr i32, i32* %ps, i32 1 - store i32 %n1, i32* %ps1 - - %p2 = getelementptr [9 x i8], [9 x i8]* @i_1_2_3_, i32 0, i32 2 - %n2 = call i32 @strtol(i8* %p2, i8** @endptr, i32 10) - %ps2 = getelementptr i32, i32* %ps, i32 2 - store i32 %n2, i32* %ps2 - - %p3 = getelementptr [9 x i8], [9 x i8]* @i_1_2_3_, i32 0, i32 4 - %n3 = call i32 @strtol(i8* %p3, i8** @endptr, i32 10) - %ps3 = getelementptr i32, i32* %ps, i32 3 - store i32 %n3, i32* %ps3 + %n1 = call i32 @strtol(ptr @i_1_2_3_, ptr @endptr, i32 10) + %ps1 = getelementptr i32, ptr %ps, i32 1 + store i32 %n1, ptr %ps1 + + %p2 = getelementptr [9 x i8], ptr @i_1_2_3_, i32 0, i32 2 + %n2 = call i32 @strtol(ptr %p2, ptr @endptr, i32 10) + %ps2 = getelementptr i32, ptr %ps, i32 2 + store i32 %n2, ptr %ps2 + + %p3 = getelementptr [9 x i8], ptr @i_1_2_3_, i32 0, i32 4 + %n3 = call i32 @strtol(ptr %p3, ptr @endptr, i32 10) + %ps3 = getelementptr i32, ptr %ps, i32 3 + store i32 %n3, ptr %ps3 ret void } diff --git a/llvm/test/Transforms/InstCombine/str-int-5.ll b/llvm/test/Transforms/InstCombine/str-int-5.ll --- a/llvm/test/Transforms/InstCombine/str-int-5.ll +++ b/llvm/test/Transforms/InstCombine/str-int-5.ll @@ -4,8 +4,8 @@ ; ; RUN: opt < %s -passes=instcombine -S | FileCheck %s -declare i32 @strtoul(i8*, i8**, i32) -declare i64 @strtoull(i8*, i8**, i32) +declare i32 @strtoul(ptr, ptr, i32) +declare i64 @strtoull(ptr, ptr, i32) ; All POSIX whitespace characters. @@ -39,122 +39,109 @@ @x64max = constant [20 x i8] c" 0xffffffffffffffff\00" @ui64max_p1 = constant [22 x i8] c" 18446744073709551616\00" -@endptr = external global i8* +@endptr = external global ptr ; Exercise folding calls to 32-bit strtoul. -define void @fold_strtoul(i32* %ps) { +define void @fold_strtoul(ptr %ps) { ; CHECK-LABEL: @fold_strtoul( -; CHECK-NEXT: store i8* getelementptr inbounds ([11 x i8], [11 x i8]* @ws_im123, i64 0, i64 10), i8** @endptr, align 8 -; CHECK-NEXT: store i32 -123, i32* [[PS:%.*]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([11 x i8], [11 x i8]* @ws_ip234, i64 0, i64 10), i8** @endptr, align 8 -; CHECK-NEXT: [[PS1:%.*]] = getelementptr i32, i32* [[PS]], i64 1 -; CHECK-NEXT: store i32 234, i32* [[PS1]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([13 x i8], [13 x i8]* @i32min_m1, i64 0, i64 12), i8** @endptr, align 8 -; CHECK-NEXT: [[PS2:%.*]] = getelementptr i32, i32* [[PS]], i64 2 -; CHECK-NEXT: store i32 2147483647, i32* [[PS2]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([13 x i8], [13 x i8]* @i32min, i64 0, i64 12), i8** @endptr, align 8 -; CHECK-NEXT: [[PS3:%.*]] = getelementptr i32, i32* [[PS]], i64 3 -; CHECK-NEXT: store i32 -2147483648, i32* [[PS3]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([15 x i8], [15 x i8]* @o32min, i64 0, i64 14), i8** @endptr, align 8 -; CHECK-NEXT: [[PS4:%.*]] = getelementptr i32, i32* [[PS]], i64 4 -; CHECK-NEXT: store i32 -2147483648, i32* [[PS4]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([15 x i8], [15 x i8]* @mo32min, i64 0, i64 14), i8** @endptr, align 8 -; CHECK-NEXT: [[PS5:%.*]] = getelementptr i32, i32* [[PS]], i64 5 -; CHECK-NEXT: store i32 -2147483648, i32* [[PS5]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([13 x i8], [13 x i8]* @x32min, i64 0, i64 12), i8** @endptr, align 8 -; CHECK-NEXT: [[PS6:%.*]] = getelementptr i32, i32* [[PS]], i64 6 -; CHECK-NEXT: store i32 -2147483648, i32* [[PS6]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([13 x i8], [13 x i8]* @mx32min, i64 0, i64 12), i8** @endptr, align 8 -; CHECK-NEXT: [[PS7:%.*]] = getelementptr i32, i32* [[PS]], i64 7 -; CHECK-NEXT: store i32 -2147483648, i32* [[PS7]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([12 x i8], [12 x i8]* @i32max, i64 0, i64 11), i8** @endptr, align 8 -; CHECK-NEXT: [[PS8:%.*]] = getelementptr i32, i32* [[PS]], i64 8 -; CHECK-NEXT: store i32 2147483647, i32* [[PS8]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([6 x i8], [6 x i8]* @mX01, i64 0, i64 5), i8** @endptr, align 8 -; CHECK-NEXT: [[PS9:%.*]] = getelementptr i32, i32* [[PS]], i64 9 -; CHECK-NEXT: store i32 -1, i32* [[PS9]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([12 x i8], [12 x i8]* @i32max_p1, i64 0, i64 11), i8** @endptr, align 8 -; CHECK-NEXT: [[PS10:%.*]] = getelementptr i32, i32* [[PS]], i64 10 -; CHECK-NEXT: store i32 -2147483648, i32* [[PS10]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([12 x i8], [12 x i8]* @ui32max, i64 0, i64 11), i8** @endptr, align 8 -; CHECK-NEXT: [[PS11:%.*]] = getelementptr i32, i32* [[PS]], i64 11 -; CHECK-NEXT: store i32 -1, i32* [[PS11]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([11 x i8], ptr @ws_im123, i64 0, i64 10), ptr @endptr, align 8 +; CHECK-NEXT: store i32 -123, ptr [[PS:%.*]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([11 x i8], ptr @ws_ip234, i64 0, i64 10), ptr @endptr, align 8 +; CHECK-NEXT: [[PS1:%.*]] = getelementptr i32, ptr [[PS]], i64 1 +; CHECK-NEXT: store i32 234, ptr [[PS1]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([13 x i8], ptr @i32min_m1, i64 0, i64 12), ptr @endptr, align 8 +; CHECK-NEXT: [[PS2:%.*]] = getelementptr i32, ptr [[PS]], i64 2 +; CHECK-NEXT: store i32 2147483647, ptr [[PS2]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([13 x i8], ptr @i32min, i64 0, i64 12), ptr @endptr, align 8 +; CHECK-NEXT: [[PS3:%.*]] = getelementptr i32, ptr [[PS]], i64 3 +; CHECK-NEXT: store i32 -2147483648, ptr [[PS3]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([15 x i8], ptr @o32min, i64 0, i64 14), ptr @endptr, align 8 +; CHECK-NEXT: [[PS4:%.*]] = getelementptr i32, ptr [[PS]], i64 4 +; CHECK-NEXT: store i32 -2147483648, ptr [[PS4]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([15 x i8], ptr @mo32min, i64 0, i64 14), ptr @endptr, align 8 +; CHECK-NEXT: [[PS5:%.*]] = getelementptr i32, ptr [[PS]], i64 5 +; CHECK-NEXT: store i32 -2147483648, ptr [[PS5]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([13 x i8], ptr @x32min, i64 0, i64 12), ptr @endptr, align 8 +; CHECK-NEXT: [[PS6:%.*]] = getelementptr i32, ptr [[PS]], i64 6 +; CHECK-NEXT: store i32 -2147483648, ptr [[PS6]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([13 x i8], ptr @mx32min, i64 0, i64 12), ptr @endptr, align 8 +; CHECK-NEXT: [[PS7:%.*]] = getelementptr i32, ptr [[PS]], i64 7 +; CHECK-NEXT: store i32 -2147483648, ptr [[PS7]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([12 x i8], ptr @i32max, i64 0, i64 11), ptr @endptr, align 8 +; CHECK-NEXT: [[PS8:%.*]] = getelementptr i32, ptr [[PS]], i64 8 +; CHECK-NEXT: store i32 2147483647, ptr [[PS8]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([6 x i8], ptr @mX01, i64 0, i64 5), ptr @endptr, align 8 +; CHECK-NEXT: [[PS9:%.*]] = getelementptr i32, ptr [[PS]], i64 9 +; CHECK-NEXT: store i32 -1, ptr [[PS9]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([12 x i8], ptr @i32max_p1, i64 0, i64 11), ptr @endptr, align 8 +; CHECK-NEXT: [[PS10:%.*]] = getelementptr i32, ptr [[PS]], i64 10 +; CHECK-NEXT: store i32 -2147483648, ptr [[PS10]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([12 x i8], ptr @ui32max, i64 0, i64 11), ptr @endptr, align 8 +; CHECK-NEXT: [[PS11:%.*]] = getelementptr i32, ptr [[PS]], i64 11 +; CHECK-NEXT: store i32 -1, ptr [[PS11]], align 4 ; CHECK-NEXT: ret void ; ; Fold a valid sequence with leading POSIX whitespace and a minus to ; (uint32_t)-123. - %pwsm123 = getelementptr [11 x i8], [11 x i8]* @ws_im123, i32 0, i32 0 - %im123 = call i32 @strtoul(i8* %pwsm123, i8** @endptr, i32 10) - %ps0 = getelementptr i32, i32* %ps, i32 0 - store i32 %im123, i32* %ps0 + %im123 = call i32 @strtoul(ptr @ws_im123, ptr @endptr, i32 10) + store i32 %im123, ptr %ps ; Fold a valid sequence with leading POSIX whitespace and a plus to +234. - %pwsp234 = getelementptr [11 x i8], [11 x i8]* @ws_ip234, i32 0, i32 0 - %ip234 = call i32 @strtoul(i8* %pwsp234, i8** @endptr, i32 10) - %ps1 = getelementptr i32, i32* %ps, i32 1 - store i32 %ip234, i32* %ps1 + %ip234 = call i32 @strtoul(ptr @ws_ip234, ptr @endptr, i32 10) + %ps1 = getelementptr i32, ptr %ps, i32 1 + store i32 %ip234, ptr %ps1 ; Fold the result of conversion that's equal to INT32_MIN - 1. - %psi32minm1 = getelementptr [13 x i8], [13 x i8]* @i32min_m1, i32 0, i32 0 - %i32min32m1 = call i32 @strtoul(i8* %psi32minm1, i8** @endptr, i32 10) - %ps2 = getelementptr i32, i32* %ps, i32 2 - store i32 %i32min32m1, i32* %ps2 + %i32min32m1 = call i32 @strtoul(ptr @i32min_m1, ptr @endptr, i32 10) + %ps2 = getelementptr i32, ptr %ps, i32 2 + store i32 %i32min32m1, ptr %ps2 ; Fold INT32_MIN. - %psi32min = getelementptr [13 x i8], [13 x i8]* @i32min, i32 0, i32 0 - %i32min = call i32 @strtoul(i8* %psi32min, i8** @endptr, i32 10) - %ps3 = getelementptr i32, i32* %ps, i32 3 - store i32 %i32min, i32* %ps3 + %i32min = call i32 @strtoul(ptr @i32min, ptr @endptr, i32 10) + %ps3 = getelementptr i32, ptr %ps, i32 3 + store i32 %i32min, ptr %ps3 ; Fold INT32_MIN in octal. - %pso32min = getelementptr [15 x i8], [15 x i8]* @o32min, i32 0, i32 0 - %o32min = call i32 @strtoul(i8* %pso32min, i8** @endptr, i32 0) - %ps4 = getelementptr i32, i32* %ps, i32 4 - store i32 %o32min, i32* %ps4 + %o32min = call i32 @strtoul(ptr @o32min, ptr @endptr, i32 0) + %ps4 = getelementptr i32, ptr %ps, i32 4 + store i32 %o32min, ptr %ps4 ; Fold -INT32_MIN in octal. - %psmo32min = getelementptr [15 x i8], [15 x i8]* @mo32min, i32 0, i32 0 - %mo32min = call i32 @strtoul(i8* %psmo32min, i8** @endptr, i32 0) - %ps5 = getelementptr i32, i32* %ps, i32 5 - store i32 %mo32min, i32* %ps5 + %mo32min = call i32 @strtoul(ptr @mo32min, ptr @endptr, i32 0) + %ps5 = getelementptr i32, ptr %ps, i32 5 + store i32 %mo32min, ptr %ps5 ; Fold INT32_MIN in hex. - %psx32min = getelementptr [13 x i8], [13 x i8]* @x32min, i32 0, i32 0 - %x32min = call i32 @strtoul(i8* %psx32min, i8** @endptr, i32 0) - %ps6 = getelementptr i32, i32* %ps, i32 6 - store i32 %x32min, i32* %ps6 + %x32min = call i32 @strtoul(ptr @x32min, ptr @endptr, i32 0) + %ps6 = getelementptr i32, ptr %ps, i32 6 + store i32 %x32min, ptr %ps6 ; Fold -INT32_MIN in hex. - %psmx32min = getelementptr [13 x i8], [13 x i8]* @mx32min, i32 0, i32 0 - %mx32min = call i32 @strtoul(i8* %psmx32min, i8** @endptr, i32 0) - %ps7 = getelementptr i32, i32* %ps, i32 7 - store i32 %x32min, i32* %ps7 + %mx32min = call i32 @strtoul(ptr @mx32min, ptr @endptr, i32 0) + %ps7 = getelementptr i32, ptr %ps, i32 7 + store i32 %x32min, ptr %ps7 ; Fold INT32_MAX. - %psi32max = getelementptr [12 x i8], [12 x i8]* @i32max, i32 0, i32 0 - %i32max = call i32 @strtoul(i8* %psi32max, i8** @endptr, i32 10) - %ps8 = getelementptr i32, i32* %ps, i32 8 - store i32 %i32max, i32* %ps8 + %i32max = call i32 @strtoul(ptr @i32max, ptr @endptr, i32 10) + %ps8 = getelementptr i32, ptr %ps, i32 8 + store i32 %i32max, ptr %ps8 ; Fold -0x01. - %psmX01 = getelementptr [6 x i8], [6 x i8]* @mX01, i32 0, i32 0 - %mX01 = call i32 @strtoul(i8* %psmX01, i8** @endptr, i32 0) - %ps9 = getelementptr i32, i32* %ps, i32 9 - store i32 %mX01, i32* %ps9 + %mX01 = call i32 @strtoul(ptr @mX01, ptr @endptr, i32 0) + %ps9 = getelementptr i32, ptr %ps, i32 9 + store i32 %mX01, ptr %ps9 ; Fold the result of conversion that's equal to INT32_MAX + 1. - %psmax32p1 = getelementptr [12 x i8], [12 x i8]* @i32max_p1, i32 0, i32 0 - %i32max32p1 = call i32 @strtoul(i8* %psmax32p1, i8** @endptr, i32 10) - %ps10 = getelementptr i32, i32* %ps, i32 10 - store i32 %i32max32p1, i32* %ps10 + %i32max32p1 = call i32 @strtoul(ptr @i32max_p1, ptr @endptr, i32 10) + %ps10 = getelementptr i32, ptr %ps, i32 10 + store i32 %i32max32p1, ptr %ps10 ; Fold UINT32_MAX. - %psmax = getelementptr [12 x i8], [12 x i8]* @ui32max, i32 0, i32 0 - %ui32max = call i32 @strtoul(i8* %psmax, i8** @endptr, i32 10) - %ps11 = getelementptr i32, i32* %ps, i32 11 - store i32 %ui32max, i32* %ps11 + %ui32max = call i32 @strtoul(ptr @ui32max, ptr @endptr, i32 10) + %ps11 = getelementptr i32, ptr %ps, i32 11 + store i32 %ui32max, ptr %ps11 ret void } @@ -162,47 +149,43 @@ ; Exercise not folding calls to 32-bit strtoul. -define void @call_strtoul(i32* %ps) { +define void @call_strtoul(ptr %ps) { ; CHECK-LABEL: @call_strtoul( -; CHECK-NEXT: [[MINM1:%.*]] = call i32 @strtoul(i8* getelementptr inbounds ([22 x i8], [22 x i8]* @i64min_m1, i64 0, i64 0), i8** nonnull @endptr, i32 10) -; CHECK-NEXT: store i32 [[MINM1]], i32* [[PS:%.*]], align 4 -; CHECK-NEXT: [[MAXP1:%.*]] = call i32 @strtoul(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @ui32max_p1, i64 0, i64 0), i8** nonnull @endptr, i32 10) -; CHECK-NEXT: [[PS1:%.*]] = getelementptr i32, i32* [[PS]], i64 1 -; CHECK-NEXT: store i32 [[MAXP1]], i32* [[PS1]], align 4 -; CHECK-NEXT: [[NWS:%.*]] = call i32 @strtoul(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @ws, i64 0, i64 0), i8** nonnull @endptr, i32 10) -; CHECK-NEXT: [[PS2:%.*]] = getelementptr i32, i32* [[PS]], i64 2 -; CHECK-NEXT: store i32 [[NWS]], i32* [[PS2]], align 4 -; CHECK-NEXT: [[NWSP6:%.*]] = call i32 @strtoul(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @ws, i64 0, i64 6), i8** nonnull @endptr, i32 10) -; CHECK-NEXT: [[PS3:%.*]] = getelementptr i32, i32* [[PS]], i64 3 -; CHECK-NEXT: store i32 [[NWSP6]], i32* [[PS3]], align 4 +; CHECK-NEXT: [[MINM1:%.*]] = call i32 @strtoul(ptr nonnull @i64min_m1, ptr nonnull @endptr, i32 10) +; CHECK-NEXT: store i32 [[MINM1]], ptr [[PS:%.*]], align 4 +; CHECK-NEXT: [[MAXP1:%.*]] = call i32 @strtoul(ptr nonnull @ui32max_p1, ptr nonnull @endptr, i32 10) +; CHECK-NEXT: [[PS1:%.*]] = getelementptr i32, ptr [[PS]], i64 1 +; CHECK-NEXT: store i32 [[MAXP1]], ptr [[PS1]], align 4 +; CHECK-NEXT: [[NWS:%.*]] = call i32 @strtoul(ptr nonnull @ws, ptr nonnull @endptr, i32 10) +; CHECK-NEXT: [[PS2:%.*]] = getelementptr i32, ptr [[PS]], i64 2 +; CHECK-NEXT: store i32 [[NWS]], ptr [[PS2]], align 4 +; CHECK-NEXT: [[NWSP6:%.*]] = call i32 @strtoul(ptr getelementptr inbounds ([7 x i8], ptr @ws, i64 0, i64 6), ptr nonnull @endptr, i32 10) +; CHECK-NEXT: [[PS3:%.*]] = getelementptr i32, ptr [[PS]], i64 3 +; CHECK-NEXT: store i32 [[NWSP6]], ptr [[PS3]], align 4 ; CHECK-NEXT: ret void ; ; Do not fold the result of conversion that overflows uint32_t. This ; could be folded into a constant provided errnor were set to ERANGE. - %psminm1 = getelementptr [22 x i8], [22 x i8]* @i64min_m1, i32 0, i32 0 - %minm1 = call i32 @strtoul(i8* %psminm1, i8** @endptr, i32 10) - %ps0 = getelementptr i32, i32* %ps, i32 0 - store i32 %minm1, i32* %ps0 + %minm1 = call i32 @strtoul(ptr @i64min_m1, ptr @endptr, i32 10) + store i32 %minm1, ptr %ps ; Do not fold the result of conversion that's greater than UINT32_MAX ; (same logic as above applies here). - %psui32maxp1 = getelementptr [12 x i8], [12 x i8]* @ui32max_p1, i32 0, i32 0 - %maxp1 = call i32 @strtoul(i8* %psui32maxp1, i8** @endptr, i32 10) - %ps1 = getelementptr i32, i32* %ps, i32 1 - store i32 %maxp1, i32* %ps1 + %maxp1 = call i32 @strtoul(ptr @ui32max_p1, ptr @endptr, i32 10) + %ps1 = getelementptr i32, ptr %ps, i32 1 + store i32 %maxp1, ptr %ps1 ; Do not fold a sequence consisting of just whitespace characters. - %psws = getelementptr [7 x i8], [7 x i8]* @ws, i32 0, i32 0 - %nws = call i32 @strtoul(i8* %psws, i8** @endptr, i32 10) - %ps2 = getelementptr i32, i32* %ps, i32 2 - store i32 %nws, i32* %ps2 + %nws = call i32 @strtoul(ptr @ws, ptr @endptr, i32 10) + %ps2 = getelementptr i32, ptr %ps, i32 2 + store i32 %nws, ptr %ps2 ; Do not fold an empty sequence. The library call may or may not end up ; storing EINVAL in errno. - %pswsp6 = getelementptr [7 x i8], [7 x i8]* @ws, i32 0, i32 6 - %nwsp6 = call i32 @strtoul(i8* %pswsp6, i8** @endptr, i32 10) - %ps3 = getelementptr i32, i32* %ps, i32 3 - store i32 %nwsp6, i32* %ps3 + %pswsp6 = getelementptr [7 x i8], ptr @ws, i32 0, i32 6 + %nwsp6 = call i32 @strtoul(ptr %pswsp6, ptr @endptr, i32 10) + %ps3 = getelementptr i32, ptr %ps, i32 3 + store i32 %nwsp6, ptr %ps3 ret void } @@ -210,108 +193,96 @@ ; Exercise folding calls to 64-bit strtoull. -define void @fold_strtoull(i64* %ps) { +define void @fold_strtoull(ptr %ps) { ; CHECK-LABEL: @fold_strtoull( -; CHECK-NEXT: store i8* getelementptr inbounds ([11 x i8], [11 x i8]* @ws_im123, i64 0, i64 10), i8** @endptr, align 8 -; CHECK-NEXT: store i64 -123, i64* [[PS:%.*]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([11 x i8], [11 x i8]* @ws_ip234, i64 0, i64 10), i8** @endptr, align 8 -; CHECK-NEXT: [[PS1:%.*]] = getelementptr i64, i64* [[PS]], i64 1 -; CHECK-NEXT: store i64 234, i64* [[PS1]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([22 x i8], [22 x i8]* @i64min_m1, i64 0, i64 21), i8** @endptr, align 8 -; CHECK-NEXT: [[PS2:%.*]] = getelementptr i64, i64* [[PS]], i64 2 -; CHECK-NEXT: store i64 9223372036854775807, i64* [[PS2]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([13 x i8], [13 x i8]* @i32min, i64 0, i64 12), i8** @endptr, align 8 -; CHECK-NEXT: [[PS3:%.*]] = getelementptr i64, i64* [[PS]], i64 3 -; CHECK-NEXT: store i64 -2147483648, i64* [[PS3]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([15 x i8], [15 x i8]* @o32min, i64 0, i64 14), i8** @endptr, align 8 -; CHECK-NEXT: [[PS4:%.*]] = getelementptr i64, i64* [[PS]], i64 4 -; CHECK-NEXT: store i64 2147483648, i64* [[PS4]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([13 x i8], [13 x i8]* @x32min, i64 0, i64 12), i8** @endptr, align 8 -; CHECK-NEXT: [[PS5:%.*]] = getelementptr i64, i64* [[PS]], i64 5 -; CHECK-NEXT: store i64 2147483648, i64* [[PS5]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([22 x i8], [22 x i8]* @i64min, i64 0, i64 21), i8** @endptr, align 8 -; CHECK-NEXT: [[PS6:%.*]] = getelementptr i64, i64* [[PS]], i64 6 -; CHECK-NEXT: store i64 -9223372036854775808, i64* [[PS6]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([21 x i8], [21 x i8]* @i64max, i64 0, i64 20), i8** @endptr, align 8 -; CHECK-NEXT: [[PS7:%.*]] = getelementptr i64, i64* [[PS]], i64 7 -; CHECK-NEXT: store i64 9223372036854775807, i64* [[PS7]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([21 x i8], [21 x i8]* @i64max_p1, i64 0, i64 20), i8** @endptr, align 8 -; CHECK-NEXT: [[PS8:%.*]] = getelementptr i64, i64* [[PS]], i64 8 -; CHECK-NEXT: store i64 -9223372036854775808, i64* [[PS8]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([22 x i8], [22 x i8]* @ui64max, i64 0, i64 21), i8** @endptr, align 8 -; CHECK-NEXT: [[PS9:%.*]] = getelementptr i64, i64* [[PS]], i64 9 -; CHECK-NEXT: store i64 -1, i64* [[PS9]], align 4 -; CHECK-NEXT: store i8* getelementptr inbounds ([20 x i8], [20 x i8]* @x64max, i64 0, i64 19), i8** @endptr, align 8 -; CHECK-NEXT: [[PS10:%.*]] = getelementptr i64, i64* [[PS]], i64 10 -; CHECK-NEXT: store i64 -1, i64* [[PS10]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([11 x i8], ptr @ws_im123, i64 0, i64 10), ptr @endptr, align 8 +; CHECK-NEXT: store i64 -123, ptr [[PS:%.*]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([11 x i8], ptr @ws_ip234, i64 0, i64 10), ptr @endptr, align 8 +; CHECK-NEXT: [[PS1:%.*]] = getelementptr i64, ptr [[PS]], i64 1 +; CHECK-NEXT: store i64 234, ptr [[PS1]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([22 x i8], ptr @i64min_m1, i64 0, i64 21), ptr @endptr, align 8 +; CHECK-NEXT: [[PS2:%.*]] = getelementptr i64, ptr [[PS]], i64 2 +; CHECK-NEXT: store i64 9223372036854775807, ptr [[PS2]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([13 x i8], ptr @i32min, i64 0, i64 12), ptr @endptr, align 8 +; CHECK-NEXT: [[PS3:%.*]] = getelementptr i64, ptr [[PS]], i64 3 +; CHECK-NEXT: store i64 -2147483648, ptr [[PS3]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([15 x i8], ptr @o32min, i64 0, i64 14), ptr @endptr, align 8 +; CHECK-NEXT: [[PS4:%.*]] = getelementptr i64, ptr [[PS]], i64 4 +; CHECK-NEXT: store i64 2147483648, ptr [[PS4]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([13 x i8], ptr @x32min, i64 0, i64 12), ptr @endptr, align 8 +; CHECK-NEXT: [[PS5:%.*]] = getelementptr i64, ptr [[PS]], i64 5 +; CHECK-NEXT: store i64 2147483648, ptr [[PS5]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([22 x i8], ptr @i64min, i64 0, i64 21), ptr @endptr, align 8 +; CHECK-NEXT: [[PS6:%.*]] = getelementptr i64, ptr [[PS]], i64 6 +; CHECK-NEXT: store i64 -9223372036854775808, ptr [[PS6]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([21 x i8], ptr @i64max, i64 0, i64 20), ptr @endptr, align 8 +; CHECK-NEXT: [[PS7:%.*]] = getelementptr i64, ptr [[PS]], i64 7 +; CHECK-NEXT: store i64 9223372036854775807, ptr [[PS7]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([21 x i8], ptr @i64max_p1, i64 0, i64 20), ptr @endptr, align 8 +; CHECK-NEXT: [[PS8:%.*]] = getelementptr i64, ptr [[PS]], i64 8 +; CHECK-NEXT: store i64 -9223372036854775808, ptr [[PS8]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([22 x i8], ptr @ui64max, i64 0, i64 21), ptr @endptr, align 8 +; CHECK-NEXT: [[PS9:%.*]] = getelementptr i64, ptr [[PS]], i64 9 +; CHECK-NEXT: store i64 -1, ptr [[PS9]], align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([20 x i8], ptr @x64max, i64 0, i64 19), ptr @endptr, align 8 +; CHECK-NEXT: [[PS10:%.*]] = getelementptr i64, ptr [[PS]], i64 10 +; CHECK-NEXT: store i64 -1, ptr [[PS10]], align 4 ; CHECK-NEXT: ret void ; ; Fold a valid sequence with leading POSIX whitespace and a minus to ; (uint64_t)-123. - %pwsm123 = getelementptr [11 x i8], [11 x i8]* @ws_im123, i32 0, i32 0 - %im123 = call i64 @strtoull(i8* %pwsm123, i8** @endptr, i32 10) - %ps0 = getelementptr i64, i64* %ps, i32 0 - store i64 %im123, i64* %ps0 + %im123 = call i64 @strtoull(ptr @ws_im123, ptr @endptr, i32 10) + store i64 %im123, ptr %ps ; Fold a valid sequence with leading POSIX whitespace and a plus to +234. - %pwsp234 = getelementptr [11 x i8], [11 x i8]* @ws_ip234, i32 0, i32 0 - %ip234 = call i64 @strtoull(i8* %pwsp234, i8** @endptr, i32 10) - %ps1 = getelementptr i64, i64* %ps, i32 1 - store i64 %ip234, i64* %ps1 + %ip234 = call i64 @strtoull(ptr @ws_ip234, ptr @endptr, i32 10) + %ps1 = getelementptr i64, ptr %ps, i32 1 + store i64 %ip234, ptr %ps1 ; Fold the result of conversion that's equal to INT64_MIN - 1. - %psi64minm1 = getelementptr [22 x i8], [22 x i8]* @i64min_m1, i32 0, i32 0 - %i64min32m1 = call i64 @strtoull(i8* %psi64minm1, i8** @endptr, i32 10) - %ps2 = getelementptr i64, i64* %ps, i32 2 - store i64 %i64min32m1, i64* %ps2 + %i64min32m1 = call i64 @strtoull(ptr @i64min_m1, ptr @endptr, i32 10) + %ps2 = getelementptr i64, ptr %ps, i32 2 + store i64 %i64min32m1, ptr %ps2 ; Fold INT32_MIN. - %psi32min = getelementptr [13 x i8], [13 x i8]* @i32min, i32 0, i32 0 - %i32min = call i64 @strtoull(i8* %psi32min, i8** @endptr, i32 10) - %ps3 = getelementptr i64, i64* %ps, i32 3 - store i64 %i32min, i64* %ps3 + %i32min = call i64 @strtoull(ptr @i32min, ptr @endptr, i32 10) + %ps3 = getelementptr i64, ptr %ps, i32 3 + store i64 %i32min, ptr %ps3 ; Fold INT32_MIN in octal. - %pso32min = getelementptr [15 x i8], [15 x i8]* @o32min, i32 0, i32 0 - %o32min = call i64 @strtoull(i8* %pso32min, i8** @endptr, i32 0) - %ps4 = getelementptr i64, i64* %ps, i32 4 - store i64 %o32min, i64* %ps4 + %o32min = call i64 @strtoull(ptr @o32min, ptr @endptr, i32 0) + %ps4 = getelementptr i64, ptr %ps, i32 4 + store i64 %o32min, ptr %ps4 ; Fold INT32_MIN in hex. - %psx32min = getelementptr [13 x i8], [13 x i8]* @x32min, i32 0, i32 0 - %x32min = call i64 @strtoull(i8* %psx32min, i8** @endptr, i32 0) - %ps5 = getelementptr i64, i64* %ps, i32 5 - store i64 %x32min, i64* %ps5 + %x32min = call i64 @strtoull(ptr @x32min, ptr @endptr, i32 0) + %ps5 = getelementptr i64, ptr %ps, i32 5 + store i64 %x32min, ptr %ps5 ; Fold INT64_MIN. - %psi64min = getelementptr [22 x i8], [22 x i8]* @i64min, i32 0, i32 0 - %i64min = call i64 @strtoull(i8* %psi64min, i8** @endptr, i32 10) - %ps6 = getelementptr i64, i64* %ps, i32 6 - store i64 %i64min, i64* %ps6 + %i64min = call i64 @strtoull(ptr @i64min, ptr @endptr, i32 10) + %ps6 = getelementptr i64, ptr %ps, i32 6 + store i64 %i64min, ptr %ps6 ; Fold INT64_MAX. - %psi64max = getelementptr [21 x i8], [21 x i8]* @i64max, i32 0, i32 0 - %i64max = call i64 @strtoull(i8* %psi64max, i8** @endptr, i32 10) - %ps7 = getelementptr i64, i64* %ps, i32 7 - store i64 %i64max, i64* %ps7 + %i64max = call i64 @strtoull(ptr @i64max, ptr @endptr, i32 10) + %ps7 = getelementptr i64, ptr %ps, i32 7 + store i64 %i64max, ptr %ps7 ; Fold the result of conversion that's equal to INT64_MAX + 1 to INT64_MIN. - %psmax32p1 = getelementptr [21 x i8], [21 x i8]* @i64max_p1, i32 0, i32 0 - %i64max32p1 = call i64 @strtoull(i8* %psmax32p1, i8** @endptr, i32 10) - %ps8 = getelementptr i64, i64* %ps, i32 8 - store i64 %i64max32p1, i64* %ps8 + %i64max32p1 = call i64 @strtoull(ptr @i64max_p1, ptr @endptr, i32 10) + %ps8 = getelementptr i64, ptr %ps, i32 8 + store i64 %i64max32p1, ptr %ps8 ; Fold UINT64_MAX. - %psmax = getelementptr [22 x i8], [22 x i8]* @ui64max, i32 0, i32 0 - %ui64max = call i64 @strtoull(i8* %psmax, i8** @endptr, i32 10) - %ps9 = getelementptr i64, i64* %ps, i32 9 - store i64 %ui64max, i64* %ps9 + %ui64max = call i64 @strtoull(ptr @ui64max, ptr @endptr, i32 10) + %ps9 = getelementptr i64, ptr %ps, i32 9 + store i64 %ui64max, ptr %ps9 ; Fold UINT64_MAX in hex. - %psxmax = getelementptr [20 x i8], [20 x i8]* @x64max, i32 0, i32 0 - %x64max = call i64 @strtoull(i8* %psxmax, i8** @endptr, i32 0) - %ps10 = getelementptr i64, i64* %ps, i32 10 - store i64 %x64max, i64* %ps10 + %x64max = call i64 @strtoull(ptr @x64max, ptr @endptr, i32 0) + %ps10 = getelementptr i64, ptr %ps, i32 10 + store i64 %x64max, ptr %ps10 ret void } @@ -319,38 +290,36 @@ ; Exercise not folding calls to 64-bit strtoull. -define void @call_strtoull(i64* %ps) { +define void @call_strtoull(ptr %ps) { ; CHECK-LABEL: @call_strtoull( -; CHECK-NEXT: [[MAXP1:%.*]] = call i64 @strtoull(i8* getelementptr inbounds ([22 x i8], [22 x i8]* @ui64max_p1, i64 0, i64 0), i8** nonnull @endptr, i32 10) -; CHECK-NEXT: [[PS1:%.*]] = getelementptr i64, i64* [[PS:%.*]], i64 1 -; CHECK-NEXT: store i64 [[MAXP1]], i64* [[PS1]], align 4 -; CHECK-NEXT: [[NWS:%.*]] = call i64 @strtoull(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @ws, i64 0, i64 0), i8** nonnull @endptr, i32 10) -; CHECK-NEXT: [[PS2:%.*]] = getelementptr i64, i64* [[PS]], i64 2 -; CHECK-NEXT: store i64 [[NWS]], i64* [[PS2]], align 4 -; CHECK-NEXT: [[NWSP6:%.*]] = call i64 @strtoull(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @ws, i64 0, i64 6), i8** nonnull @endptr, i32 10) -; CHECK-NEXT: [[PS3:%.*]] = getelementptr i64, i64* [[PS]], i64 3 -; CHECK-NEXT: store i64 [[NWSP6]], i64* [[PS3]], align 4 +; CHECK-NEXT: [[MAXP1:%.*]] = call i64 @strtoull(ptr nonnull @ui64max_p1, ptr nonnull @endptr, i32 10) +; CHECK-NEXT: [[PS1:%.*]] = getelementptr i64, ptr [[PS:%.*]], i64 1 +; CHECK-NEXT: store i64 [[MAXP1]], ptr [[PS1]], align 4 +; CHECK-NEXT: [[NWS:%.*]] = call i64 @strtoull(ptr nonnull @ws, ptr nonnull @endptr, i32 10) +; CHECK-NEXT: [[PS2:%.*]] = getelementptr i64, ptr [[PS]], i64 2 +; CHECK-NEXT: store i64 [[NWS]], ptr [[PS2]], align 4 +; CHECK-NEXT: [[NWSP6:%.*]] = call i64 @strtoull(ptr getelementptr inbounds ([7 x i8], ptr @ws, i64 0, i64 6), ptr nonnull @endptr, i32 10) +; CHECK-NEXT: [[PS3:%.*]] = getelementptr i64, ptr [[PS]], i64 3 +; CHECK-NEXT: store i64 [[NWSP6]], ptr [[PS3]], align 4 ; CHECK-NEXT: ret void ; ; Do not fold the result of conversion that overflows uint64_t. This ; could be folded into a constant provided errnor were set to ERANGE. - %psui64maxp1 = getelementptr [22 x i8], [22 x i8]* @ui64max_p1, i32 0, i32 0 - %maxp1 = call i64 @strtoull(i8* %psui64maxp1, i8** @endptr, i32 10) - %ps1 = getelementptr i64, i64* %ps, i32 1 - store i64 %maxp1, i64* %ps1 + %maxp1 = call i64 @strtoull(ptr @ui64max_p1, ptr @endptr, i32 10) + %ps1 = getelementptr i64, ptr %ps, i32 1 + store i64 %maxp1, ptr %ps1 ; Do not fold a sequence consisting of just whitespace characters. - %psws = getelementptr [7 x i8], [7 x i8]* @ws, i32 0, i32 0 - %nws = call i64 @strtoull(i8* %psws, i8** @endptr, i32 10) - %ps2 = getelementptr i64, i64* %ps, i32 2 - store i64 %nws, i64* %ps2 + %nws = call i64 @strtoull(ptr @ws, ptr @endptr, i32 10) + %ps2 = getelementptr i64, ptr %ps, i32 2 + store i64 %nws, ptr %ps2 ; Do not fold an empty sequence. The library call may or may not end up ; storing EINVAL in errno. - %pswsp6 = getelementptr [7 x i8], [7 x i8]* @ws, i32 0, i32 6 - %nwsp6 = call i64 @strtoull(i8* %pswsp6, i8** @endptr, i32 10) - %ps3 = getelementptr i64, i64* %ps, i32 3 - store i64 %nwsp6, i64* %ps3 + %pswsp6 = getelementptr [7 x i8], ptr @ws, i32 0, i32 6 + %nwsp6 = call i64 @strtoull(ptr %pswsp6, ptr @endptr, i32 10) + %ps3 = getelementptr i64, ptr %ps, i32 3 + store i64 %nwsp6, ptr %ps3 ret void } diff --git a/llvm/test/Transforms/InstCombine/str-int.ll b/llvm/test/Transforms/InstCombine/str-int.ll --- a/llvm/test/Transforms/InstCombine/str-int.ll +++ b/llvm/test/Transforms/InstCombine/str-int.ll @@ -10,17 +10,17 @@ @.str.6 = private unnamed_addr constant [10 x i8] c"499496729\00", align 1 @.str.7 = private unnamed_addr constant [11 x i8] c"4994967295\00", align 1 -declare i32 @strtol(i8*, i8**, i32) -declare i32 @atoi(i8*) -declare i32 @atol(i8*) -declare i64 @atoll(i8*) -declare i64 @strtoll(i8*, i8**, i32) +declare i32 @strtol(ptr, ptr, i32) +declare i32 @atoi(ptr) +declare i32 @atol(ptr) +declare i64 @atoll(ptr) +declare i64 @strtoll(ptr, ptr, i32) define i32 @strtol_dec() #0 { ; CHECK-LABEL: @strtol_dec( ; CHECK-NEXT: ret i32 12 ; - %call = call i32 @strtol(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i8** null, i32 10) #2 + %call = call i32 @strtol(ptr @.str, ptr null, i32 10) #2 ret i32 %call } @@ -28,7 +28,7 @@ ; CHECK-LABEL: @strtol_base_zero( ; CHECK-NEXT: ret i32 12 ; - %call = call i32 @strtol(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i8** null, i32 0) #2 + %call = call i32 @strtol(ptr @.str, ptr null, i32 0) #2 ret i32 %call } @@ -36,32 +36,32 @@ ; CHECK-LABEL: @strtol_hex( ; CHECK-NEXT: ret i32 18 ; - %call = call i32 @strtol(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i8** null, i32 16) #2 + %call = call i32 @strtol(ptr @.str, ptr null, i32 16) #2 ret i32 %call } ; Fold a call to strtol with an endptr known to be nonnull (the result ; of pointer increment). -define i32 @strtol_endptr_not_null(i8** %pend) { +define i32 @strtol_endptr_not_null(ptr %pend) { ; CHECK-LABEL: @strtol_endptr_not_null( -; CHECK-NEXT: [[ENDP1:%.*]] = getelementptr inbounds i8*, i8** [[PEND:%.*]], i64 1 -; CHECK-NEXT: store i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 2), i8** [[ENDP1]], align 8 +; CHECK-NEXT: [[ENDP1:%.*]] = getelementptr inbounds ptr, ptr [[PEND:%.*]], i64 1 +; CHECK-NEXT: store ptr getelementptr inbounds ([3 x i8], ptr @.str, i64 0, i64 2), ptr [[ENDP1]], align 8 ; CHECK-NEXT: ret i32 12 ; - %endp1 = getelementptr inbounds i8*, i8** %pend, i32 1 - %call = call i32 @strtol(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i8** %endp1, i32 10) + %endp1 = getelementptr inbounds ptr, ptr %pend, i32 1 + %call = call i32 @strtol(ptr @.str, ptr %endp1, i32 10) ret i32 %call } ; Don't fold a call to strtol with an endptr that's not known to be nonnull. -define i32 @strtol_endptr_maybe_null(i8** %end) { +define i32 @strtol_endptr_maybe_null(ptr %end) { ; CHECK-LABEL: @strtol_endptr_maybe_null( -; CHECK-NEXT: [[CALL:%.*]] = call i32 @strtol(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0), i8** [[END:%.*]], i32 10) +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strtol(ptr nonnull @.str.1, ptr [[END:%.*]], i32 10) ; CHECK-NEXT: ret i32 [[CALL]] ; - %call = call i32 @strtol(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i32 0, i32 0), i8** %end, i32 10) + %call = call i32 @strtol(ptr @.str.1, ptr %end, i32 10) ret i32 %call } @@ -69,53 +69,53 @@ ; CHECK-LABEL: @atoi_test( ; CHECK-NEXT: ret i32 12 ; - %call = call i32 @atoi(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0)) #4 + %call = call i32 @atoi(ptr @.str) #4 ret i32 %call } -define i32 @strtol_not_const_str(i8* %s) #0 { +define i32 @strtol_not_const_str(ptr %s) #0 { ; CHECK-LABEL: @strtol_not_const_str( -; CHECK-NEXT: [[CALL:%.*]] = call i32 @strtol(i8* nocapture [[S:%.*]], i8** null, i32 10) +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strtol(ptr nocapture [[S:%.*]], ptr null, i32 10) ; CHECK-NEXT: ret i32 [[CALL]] ; - %call = call i32 @strtol(i8* %s, i8** null, i32 10) #3 + %call = call i32 @strtol(ptr %s, ptr null, i32 10) #3 ret i32 %call } -define i32 @atoi_not_const_str(i8* %s) #0 { +define i32 @atoi_not_const_str(ptr %s) #0 { ; CHECK-LABEL: @atoi_not_const_str( -; CHECK-NEXT: [[CALL:%.*]] = call i32 @atoi(i8* nocapture [[S:%.*]]) +; CHECK-NEXT: [[CALL:%.*]] = call i32 @atoi(ptr nocapture [[S:%.*]]) ; CHECK-NEXT: ret i32 [[CALL]] ; - %call = call i32 @atoi(i8* %s) #4 + %call = call i32 @atoi(ptr %s) #4 ret i32 %call } define i32 @strtol_not_const_base(i32 %b) #0 { ; CHECK-LABEL: @strtol_not_const_base( -; CHECK-NEXT: [[CALL:%.*]] = call i32 @strtol(i8* nocapture getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0), i8** null, i32 [[B:%.*]]) +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strtol(ptr nocapture nonnull @.str, ptr null, i32 [[B:%.*]]) ; CHECK-NEXT: ret i32 [[CALL]] ; - %call = call i32 @strtol(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i8** null, i32 %b) #2 + %call = call i32 @strtol(ptr @.str, ptr null, i32 %b) #2 ret i32 %call } define i32 @strtol_long_int() #0 { ; CHECK-LABEL: @strtol_long_int( -; CHECK-NEXT: [[CALL:%.*]] = call i32 @strtol(i8* nocapture getelementptr inbounds ([11 x i8], [11 x i8]* @.str.2, i64 0, i64 0), i8** null, i32 10) +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strtol(ptr nocapture nonnull @.str.2, ptr null, i32 10) ; CHECK-NEXT: ret i32 [[CALL]] ; - %call = call i32 @strtol(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.2, i32 0, i32 0), i8** null, i32 10) #3 + %call = call i32 @strtol(ptr @.str.2, ptr null, i32 10) #3 ret i32 %call } define i32 @strtol_big_overflow() #0 { ; CHECK-LABEL: @strtol_big_overflow( -; CHECK-NEXT: [[CALL:%.*]] = call i32 @strtol(i8* nocapture getelementptr inbounds ([24 x i8], [24 x i8]* @.str.3, i64 0, i64 0), i8** null, i32 10) +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strtol(ptr nocapture nonnull @.str.3, ptr null, i32 10) ; CHECK-NEXT: ret i32 [[CALL]] ; - %call = call i32 @strtol(i8* nocapture getelementptr inbounds ([24 x i8], [24 x i8]* @.str.3, i32 0, i32 0), i8** null, i32 10) #2 + %call = call i32 @strtol(ptr nocapture @.str.3, ptr null, i32 10) #2 ret i32 %call } @@ -124,7 +124,7 @@ ; CHECK-NEXT: ret i32 499496729 ; ; CHECK-NEXT - %call = call i32 @atol(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.6, i32 0, i32 0)) #4 + %call = call i32 @atol(ptr @.str.6) #4 ret i32 %call } @@ -132,7 +132,7 @@ ; CHECK-LABEL: @atoll_test( ; CHECK-NEXT: ret i64 4994967295 ; - %call = call i64 @atoll(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.5, i32 0, i32 0)) #3 + %call = call i64 @atoll(ptr @.str.5) #3 ret i64 %call } @@ -141,6 +141,6 @@ ; CHECK-NEXT: ret i64 4994967295 ; ; CHECK-NEXT - %call = call i64 @strtoll(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.7, i32 0, i32 0), i8** null, i32 10) #5 + %call = call i64 @strtoll(ptr @.str.7, ptr null, i32 10) #5 ret i64 %call } diff --git a/llvm/test/Transforms/InstCombine/strcall-no-nul.ll b/llvm/test/Transforms/InstCombine/strcall-no-nul.ll --- a/llvm/test/Transforms/InstCombine/strcall-no-nul.ll +++ b/llvm/test/Transforms/InstCombine/strcall-no-nul.ll @@ -12,35 +12,35 @@ ; an in-depth discussion of the trade-offs: ; https://discourse.llvm.org/t/rfc-safe-optimizations-for-sanitizers -declare i8* @strchr(i8*, i32) -declare i8* @strrchr(i8*, i32) -declare i32 @strcmp(i8*, i8*) -declare i32 @strncmp(i8*, i8*, i64) -declare i8* @strstr(i8*, i8*) +declare ptr @strchr(ptr, i32) +declare ptr @strrchr(ptr, i32) +declare i32 @strcmp(ptr, ptr) +declare i32 @strncmp(ptr, ptr, i64) +declare ptr @strstr(ptr, ptr) -declare i8* @stpcpy(i8*, i8*) -declare i8* @strcpy(i8*, i8*) -declare i8* @stpncpy(i8*, i8*, i64) -declare i8* @strncpy(i8*, i8*, i64) +declare ptr @stpcpy(ptr, ptr) +declare ptr @strcpy(ptr, ptr) +declare ptr @stpncpy(ptr, ptr, i64) +declare ptr @strncpy(ptr, ptr, i64) -declare i64 @strlen(i8*) -declare i64 @strnlen(i8*, i64) +declare i64 @strlen(ptr) +declare i64 @strnlen(ptr, i64) -declare i8* @strpbrk(i8*, i8*) +declare ptr @strpbrk(ptr, ptr) -declare i64 @strspn(i8*, i8*) -declare i64 @strcspn(i8*, i8*) +declare i64 @strspn(ptr, ptr) +declare i64 @strcspn(ptr, ptr) -declare i32 @atoi(i8*) -declare i64 @atol(i8*) -declare i64 @atoll(i8*) -declare i64 @strtol(i8*, i8**, i32) -declare i64 @strtoll(i8*, i8**, i32) -declare i64 @strtoul(i8*, i8**, i32) -declare i64 @strtoull(i8*, i8**, i32) +declare i32 @atoi(ptr) +declare i64 @atol(ptr) +declare i64 @atoll(ptr) +declare i64 @strtol(ptr, ptr, i32) +declare i64 @strtoll(ptr, ptr, i32) +declare i64 @strtoul(ptr, ptr, i32) +declare i64 @strtoull(ptr, ptr, i32) -declare i32 @sprintf(i8*, i8*, ...) -declare i32 @snprintf(i8*, i64, i8*, ...) +declare i32 @sprintf(ptr, ptr, ...) +declare i32 @snprintf(ptr, i64, ptr, ...) @a5 = constant [5 x i8] c"%s\0045"; @@ -48,34 +48,32 @@ ; Fold strchr(a5 + 5, '\0') to null. -define i8* @fold_strchr_past_end() { +define ptr @fold_strchr_past_end() { ; CHECK-LABEL: @fold_strchr_past_end( -; CHECK-NEXT: ret i8* getelementptr inbounds ([5 x i8], [5 x i8]* @a5, i64 1, i64 0) +; CHECK-NEXT: ret ptr getelementptr inbounds ([5 x i8], ptr @a5, i64 1, i64 0) ; - %p = getelementptr [5 x i8], [5 x i8]* @a5, i32 0, i32 5 - %q = call i8* @strchr(i8* %p, i32 0) - ret i8* %q + %p = getelementptr [5 x i8], ptr @a5, i32 0, i32 5 + %q = call ptr @strchr(ptr %p, i32 0) + ret ptr %q } ; Fold strcmp(a5, a5 + 5) (and vice versa) to null. -define void @fold_strcmp_past_end(i32* %pcmp) { +define void @fold_strcmp_past_end(ptr %pcmp) { ; CHECK-LABEL: @fold_strcmp_past_end( -; CHECK-NEXT: store i32 1, i32* [[PCMP:%.*]], align 4 -; CHECK-NEXT: [[PC50:%.*]] = getelementptr i32, i32* [[PCMP]], i64 1 -; CHECK-NEXT: store i32 -1, i32* [[PC50]], align 4 +; CHECK-NEXT: store i32 1, ptr [[PCMP:%.*]], align 4 +; CHECK-NEXT: [[PC50:%.*]] = getelementptr i32, ptr [[PCMP]], i64 1 +; CHECK-NEXT: store i32 -1, ptr [[PC50]], align 4 ; CHECK-NEXT: ret void ; - %p0 = getelementptr [5 x i8], [5 x i8]* @a5, i32 0, i32 0 - %p5 = getelementptr [5 x i8], [5 x i8]* @a5, i32 0, i32 5 + %p5 = getelementptr [5 x i8], ptr @a5, i32 0, i32 5 - %c05 = call i32 @strcmp(i8* %p0, i8* %p5) - %pc05 = getelementptr i32, i32* %pcmp, i32 0 - store i32 %c05, i32* %pc05 + %c05 = call i32 @strcmp(ptr @a5, ptr %p5) + store i32 %c05, ptr %pcmp - %c50 = call i32 @strcmp(i8* %p5, i8* %p0) - %pc50 = getelementptr i32, i32* %pcmp, i32 1 - store i32 %c50, i32* %pc50 + %c50 = call i32 @strcmp(ptr %p5, ptr @a5) + %pc50 = getelementptr i32, ptr %pcmp, i32 1 + store i32 %c50, ptr %pc50 ret void } @@ -83,23 +81,21 @@ ; Likewise, fold strncmp(a5, a5 + 5, 5) (and vice versa) to null. -define void @fold_strncmp_past_end(i32* %pcmp) { +define void @fold_strncmp_past_end(ptr %pcmp) { ; CHECK-LABEL: @fold_strncmp_past_end( -; CHECK-NEXT: store i32 1, i32* [[PCMP:%.*]], align 4 -; CHECK-NEXT: [[PC50:%.*]] = getelementptr i32, i32* [[PCMP]], i64 1 -; CHECK-NEXT: store i32 -1, i32* [[PC50]], align 4 +; CHECK-NEXT: store i32 1, ptr [[PCMP:%.*]], align 4 +; CHECK-NEXT: [[PC50:%.*]] = getelementptr i32, ptr [[PCMP]], i64 1 +; CHECK-NEXT: store i32 -1, ptr [[PC50]], align 4 ; CHECK-NEXT: ret void ; - %p0 = getelementptr [5 x i8], [5 x i8]* @a5, i32 0, i32 0 - %p5 = getelementptr [5 x i8], [5 x i8]* @a5, i32 0, i32 5 + %p5 = getelementptr [5 x i8], ptr @a5, i32 0, i32 5 - %c05 = call i32 @strncmp(i8* %p0, i8* %p5, i64 5) - %pc05 = getelementptr i32, i32* %pcmp, i32 0 - store i32 %c05, i32* %pc05 + %c05 = call i32 @strncmp(ptr @a5, ptr %p5, i64 5) + store i32 %c05, ptr %pcmp - %c50 = call i32 @strncmp(i8* %p5, i8* %p0, i64 5) - %pc50 = getelementptr i32, i32* %pcmp, i32 1 - store i32 %c50, i32* %pc50 + %c50 = call i32 @strncmp(ptr %p5, ptr @a5, i64 5) + %pc50 = getelementptr i32, ptr %pcmp, i32 1 + store i32 %c50, ptr %pc50 ret void } @@ -107,35 +103,33 @@ ; Fold strrchr(a5 + 5, '\0') to poison (it's UB). -define i8* @fold_strrchr_past_end(i32 %c) { +define ptr @fold_strrchr_past_end(i32 %c) { ; CHECK-LABEL: @fold_strrchr_past_end( -; CHECK-NEXT: ret i8* poison +; CHECK-NEXT: ret ptr poison ; - %p5 = getelementptr [5 x i8], [5 x i8]* @a5, i32 0, i32 5 - %r = call i8* @strrchr(i8* %p5, i32 0) - ret i8* %r + %p5 = getelementptr [5 x i8], ptr @a5, i32 0, i32 5 + %r = call ptr @strrchr(ptr %p5, i32 0) + ret ptr %r } ; Fold strstr(a5 + 5, a5) (and vice versa) to null. -define void @fold_strstr_past_end(i8** %psub) { +define void @fold_strstr_past_end(ptr %psub) { ; CHECK-LABEL: @fold_strstr_past_end( -; CHECK-NEXT: store i8* getelementptr inbounds ([5 x i8], [5 x i8]* @a5, i64 0, i64 0), i8** [[PSUB:%.*]], align 8 -; CHECK-NEXT: [[PS50:%.*]] = getelementptr i8*, i8** [[PSUB]], i64 1 -; CHECK-NEXT: store i8* null, i8** [[PS50]], align 8 +; CHECK-NEXT: store ptr @a5, ptr [[PSUB:%.*]], align 8 +; CHECK-NEXT: [[PS50:%.*]] = getelementptr ptr, ptr [[PSUB]], i64 1 +; CHECK-NEXT: store ptr null, ptr [[PS50]], align 8 ; CHECK-NEXT: ret void ; - %p0 = getelementptr [5 x i8], [5 x i8]* @a5, i32 0, i32 0 - %p5 = getelementptr [5 x i8], [5 x i8]* @a5, i32 0, i32 5 + %p5 = getelementptr [5 x i8], ptr @a5, i32 0, i32 5 - %s05 = call i8* @strstr(i8* %p0, i8* %p5) - %ps05 = getelementptr i8*, i8** %psub, i32 0 - store i8* %s05, i8** %ps05 + %s05 = call ptr @strstr(ptr @a5, ptr %p5) + store ptr %s05, ptr %psub - %s50 = call i8* @strstr(i8* %p5, i8* %p0) - %ps50 = getelementptr i8*, i8** %psub, i32 1 - store i8* %s50, i8** %ps50 + %s50 = call ptr @strstr(ptr %p5, ptr @a5) + %ps50 = getelementptr ptr, ptr %psub, i32 1 + store ptr %s50, ptr %ps50 ret void } @@ -147,81 +141,79 @@ ; CHECK-LABEL: @fold_strlen_past_end( ; CHECK-NEXT: ret i64 0 ; - %p5 = getelementptr [5 x i8], [5 x i8]* @a5, i32 0, i32 5 - %r = call i64 @strlen(i8* %p5) + %p5 = getelementptr [5 x i8], ptr @a5, i32 0, i32 5 + %r = call i64 @strlen(ptr %p5) ret i64 %r } ; TODO: Fold stpcpy(dst, a5 + 5) to (*dst = '\0', dst). -define i8* @fold_stpcpy_past_end(i8* %dst) { +define ptr @fold_stpcpy_past_end(ptr %dst) { ; CHECK-LABEL: @fold_stpcpy_past_end( -; CHECK-NEXT: ret i8* [[DST:%.*]] +; CHECK-NEXT: ret ptr [[DST:%.*]] ; - %p5 = getelementptr [5 x i8], [5 x i8]* @a5, i32 0, i32 5 - %r = call i8* @strcpy(i8* %dst, i8* %p5) - ret i8* %r + %p5 = getelementptr [5 x i8], ptr @a5, i32 0, i32 5 + %r = call ptr @strcpy(ptr %dst, ptr %p5) + ret ptr %r } ; TODO: Fold strcpy(dst, a5 + 5) to (*dst = '\0', dst). -define i8* @fold_strcpy_past_end(i8* %dst) { +define ptr @fold_strcpy_past_end(ptr %dst) { ; CHECK-LABEL: @fold_strcpy_past_end( -; CHECK-NEXT: ret i8* [[DST:%.*]] +; CHECK-NEXT: ret ptr [[DST:%.*]] ; - %p5 = getelementptr [5 x i8], [5 x i8]* @a5, i32 0, i32 5 - %r = call i8* @strcpy(i8* %dst, i8* %p5) - ret i8* %r + %p5 = getelementptr [5 x i8], ptr @a5, i32 0, i32 5 + %r = call ptr @strcpy(ptr %dst, ptr %p5) + ret ptr %r } ; TODO: Fold stpncpy(dst, a5 + 5, 5) to (memset(dst, 0, 5), dst + 5). -define i8* @fold_stpncpy_past_end(i8* %dst) { +define ptr @fold_stpncpy_past_end(ptr %dst) { ; CHECK-LABEL: @fold_stpncpy_past_end( -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(5) [[DST:%.*]], i8 0, i64 5, i1 false) -; CHECK-NEXT: ret i8* [[DST]] +; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST:%.*]], i8 0, i64 5, i1 false) +; CHECK-NEXT: ret ptr [[DST]] ; - %p5 = getelementptr [5 x i8], [5 x i8]* @a5, i32 0, i32 5 - %r = call i8* @strncpy(i8* %dst, i8* %p5, i64 5) - ret i8* %r + %p5 = getelementptr [5 x i8], ptr @a5, i32 0, i32 5 + %r = call ptr @strncpy(ptr %dst, ptr %p5, i64 5) + ret ptr %r } ; TODO: Fold strncpy(dst, a5 + 5, 5) to memset(dst, 0, 5). -define i8* @fold_strncpy_past_end(i8* %dst) { +define ptr @fold_strncpy_past_end(ptr %dst) { ; CHECK-LABEL: @fold_strncpy_past_end( -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(5) [[DST:%.*]], i8 0, i64 5, i1 false) -; CHECK-NEXT: ret i8* [[DST]] +; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST:%.*]], i8 0, i64 5, i1 false) +; CHECK-NEXT: ret ptr [[DST]] ; - %p5 = getelementptr [5 x i8], [5 x i8]* @a5, i32 0, i32 5 - %r = call i8* @strncpy(i8* %dst, i8* %p5, i64 5) - ret i8* %r + %p5 = getelementptr [5 x i8], ptr @a5, i32 0, i32 5 + %r = call ptr @strncpy(ptr %dst, ptr %p5, i64 5) + ret ptr %r } ; Fold strpbrk(a5, a5 + 5) (and vice versa) to null. -define void @fold_strpbrk_past_end(i8** %psub) { +define void @fold_strpbrk_past_end(ptr %psub) { ; CHECK-LABEL: @fold_strpbrk_past_end( -; CHECK-NEXT: store i8* null, i8** [[PSUB:%.*]], align 8 -; CHECK-NEXT: [[PS50:%.*]] = getelementptr i8*, i8** [[PSUB]], i64 1 -; CHECK-NEXT: store i8* null, i8** [[PS50]], align 8 +; CHECK-NEXT: store ptr null, ptr [[PSUB:%.*]], align 8 +; CHECK-NEXT: [[PS50:%.*]] = getelementptr ptr, ptr [[PSUB]], i64 1 +; CHECK-NEXT: store ptr null, ptr [[PS50]], align 8 ; CHECK-NEXT: ret void ; - %p0 = getelementptr [5 x i8], [5 x i8]* @a5, i32 0, i32 0 - %p5 = getelementptr [5 x i8], [5 x i8]* @a5, i32 0, i32 5 + %p5 = getelementptr [5 x i8], ptr @a5, i32 0, i32 5 - %s05 = call i8* @strpbrk(i8* %p0, i8* %p5) - %ps05 = getelementptr i8*, i8** %psub, i32 0 - store i8* %s05, i8** %ps05 + %s05 = call ptr @strpbrk(ptr @a5, ptr %p5) + store ptr %s05, ptr %psub - %s50 = call i8* @strpbrk(i8* %p5, i8* %p0) - %ps50 = getelementptr i8*, i8** %psub, i32 1 - store i8* %s50, i8** %ps50 + %s50 = call ptr @strpbrk(ptr %p5, ptr @a5) + %ps50 = getelementptr ptr, ptr %psub, i32 1 + store ptr %s50, ptr %ps50 ret void } @@ -229,23 +221,21 @@ ; Fold strspn(a5, a5 + 5) (and vice versa) to null. -define void @fold_strspn_past_end(i64* %poff) { +define void @fold_strspn_past_end(ptr %poff) { ; CHECK-LABEL: @fold_strspn_past_end( -; CHECK-NEXT: store i64 0, i64* [[POFF:%.*]], align 4 -; CHECK-NEXT: [[PO50:%.*]] = getelementptr i64, i64* [[POFF]], i64 1 -; CHECK-NEXT: store i64 0, i64* [[PO50]], align 4 +; CHECK-NEXT: store i64 0, ptr [[POFF:%.*]], align 4 +; CHECK-NEXT: [[PO50:%.*]] = getelementptr i64, ptr [[POFF]], i64 1 +; CHECK-NEXT: store i64 0, ptr [[PO50]], align 4 ; CHECK-NEXT: ret void ; - %p0 = getelementptr [5 x i8], [5 x i8]* @a5, i32 0, i32 0 - %p5 = getelementptr [5 x i8], [5 x i8]* @a5, i32 0, i32 5 + %p5 = getelementptr [5 x i8], ptr @a5, i32 0, i32 5 - %o05 = call i64 @strspn(i8* %p0, i8* %p5) - %po05 = getelementptr i64, i64* %poff, i32 0 - store i64 %o05, i64* %po05 + %o05 = call i64 @strspn(ptr @a5, ptr %p5) + store i64 %o05, ptr %poff - %o50 = call i64 @strspn(i8* %p5, i8* %p0) - %po50 = getelementptr i64, i64* %poff, i32 1 - store i64 %o50, i64* %po50 + %o50 = call i64 @strspn(ptr %p5, ptr @a5) + %po50 = getelementptr i64, ptr %poff, i32 1 + store i64 %o50, ptr %po50 ret void } @@ -253,23 +243,21 @@ ; Fold strcspn(a5, a5 + 5) (and vice versa) to null. -define void @fold_strcspn_past_end(i64* %poff) { +define void @fold_strcspn_past_end(ptr %poff) { ; CHECK-LABEL: @fold_strcspn_past_end( -; CHECK-NEXT: store i64 2, i64* [[POFF:%.*]], align 4 -; CHECK-NEXT: [[PO50:%.*]] = getelementptr i64, i64* [[POFF]], i64 1 -; CHECK-NEXT: store i64 0, i64* [[PO50]], align 4 +; CHECK-NEXT: store i64 2, ptr [[POFF:%.*]], align 4 +; CHECK-NEXT: [[PO50:%.*]] = getelementptr i64, ptr [[POFF]], i64 1 +; CHECK-NEXT: store i64 0, ptr [[PO50]], align 4 ; CHECK-NEXT: ret void ; - %p0 = getelementptr [5 x i8], [5 x i8]* @a5, i32 0, i32 0 - %p5 = getelementptr [5 x i8], [5 x i8]* @a5, i32 0, i32 5 + %p5 = getelementptr [5 x i8], ptr @a5, i32 0, i32 5 - %o05 = call i64 @strcspn(i8* %p0, i8* %p5) - %po05 = getelementptr i64, i64* %poff, i32 0 - store i64 %o05, i64* %po05 + %o05 = call i64 @strcspn(ptr @a5, ptr %p5) + store i64 %o05, ptr %poff - %o50 = call i64 @strcspn(i8* %p5, i8* %p0) - %po50 = getelementptr i64, i64* %poff, i32 1 - store i64 %o50, i64* %po50 + %o50 = call i64 @strcspn(ptr %p5, ptr @a5) + %po50 = getelementptr i64, ptr %poff, i32 1 + store i64 %o50, ptr %po50 ret void } @@ -280,11 +268,11 @@ define i32 @fold_atoi_past_end() { ; CHECK-LABEL: @fold_atoi_past_end( -; CHECK-NEXT: [[I:%.*]] = call i32 @atoi(i8* nocapture getelementptr inbounds ([5 x i8], [5 x i8]* @a5, i64 1, i64 0)) +; CHECK-NEXT: [[I:%.*]] = call i32 @atoi(ptr nocapture getelementptr inbounds ([5 x i8], ptr @a5, i64 1, i64 0)) ; CHECK-NEXT: ret i32 [[I]] ; - %p5 = getelementptr [5 x i8], [5 x i8]* @a5, i32 0, i32 5 - %i = call i32 @atoi(i8* %p5) + %p5 = getelementptr [5 x i8], ptr @a5, i32 0, i32 5 + %i = call i32 @atoi(ptr %p5) ret i32 %i } @@ -292,52 +280,51 @@ ; for atoll and strtrol and similar. ; Verify that processing the invalid call doesn't run into trouble. -define void @fold_atol_strtol_past_end(i64* %ps) { +define void @fold_atol_strtol_past_end(ptr %ps) { ; CHECK-LABEL: @fold_atol_strtol_past_end( -; CHECK-NEXT: [[I0:%.*]] = call i64 @atol(i8* nocapture getelementptr inbounds ([5 x i8], [5 x i8]* @a5, i64 1, i64 0)) -; CHECK-NEXT: store i64 [[I0]], i64* [[PS:%.*]], align 4 -; CHECK-NEXT: [[I1:%.*]] = call i64 @atoll(i8* nocapture getelementptr inbounds ([5 x i8], [5 x i8]* @a5, i64 1, i64 0)) -; CHECK-NEXT: [[P1:%.*]] = getelementptr i64, i64* [[PS]], i64 1 -; CHECK-NEXT: store i64 [[I1]], i64* [[P1]], align 4 -; CHECK-NEXT: [[I2:%.*]] = call i64 @strtol(i8* nocapture getelementptr inbounds ([5 x i8], [5 x i8]* @a5, i64 1, i64 0), i8** null, i32 0) -; CHECK-NEXT: [[P2:%.*]] = getelementptr i64, i64* [[PS]], i64 2 -; CHECK-NEXT: store i64 [[I2]], i64* [[P2]], align 4 -; CHECK-NEXT: [[I3:%.*]] = call i64 @strtoul(i8* nocapture getelementptr inbounds ([5 x i8], [5 x i8]* @a5, i64 1, i64 0), i8** null, i32 8) -; CHECK-NEXT: [[P3:%.*]] = getelementptr i64, i64* [[PS]], i64 3 -; CHECK-NEXT: store i64 [[I3]], i64* [[P3]], align 4 -; CHECK-NEXT: [[I4:%.*]] = call i64 @strtoll(i8* nocapture getelementptr inbounds ([5 x i8], [5 x i8]* @a5, i64 1, i64 0), i8** null, i32 10) -; CHECK-NEXT: [[P4:%.*]] = getelementptr i64, i64* [[PS]], i64 4 -; CHECK-NEXT: store i64 [[I4]], i64* [[P4]], align 4 -; CHECK-NEXT: [[I5:%.*]] = call i64 @strtoul(i8* nocapture getelementptr inbounds ([5 x i8], [5 x i8]* @a5, i64 1, i64 0), i8** null, i32 16) -; CHECK-NEXT: [[P5:%.*]] = getelementptr i64, i64* [[PS]], i64 5 -; CHECK-NEXT: store i64 [[I5]], i64* [[P5]], align 4 +; CHECK-NEXT: [[I0:%.*]] = call i64 @atol(ptr nocapture getelementptr inbounds ([5 x i8], ptr @a5, i64 1, i64 0)) +; CHECK-NEXT: store i64 [[I0]], ptr [[PS:%.*]], align 4 +; CHECK-NEXT: [[I1:%.*]] = call i64 @atoll(ptr nocapture getelementptr inbounds ([5 x i8], ptr @a5, i64 1, i64 0)) +; CHECK-NEXT: [[P1:%.*]] = getelementptr i64, ptr [[PS]], i64 1 +; CHECK-NEXT: store i64 [[I1]], ptr [[P1]], align 4 +; CHECK-NEXT: [[I2:%.*]] = call i64 @strtol(ptr nocapture getelementptr inbounds ([5 x i8], ptr @a5, i64 1, i64 0), ptr null, i32 0) +; CHECK-NEXT: [[P2:%.*]] = getelementptr i64, ptr [[PS]], i64 2 +; CHECK-NEXT: store i64 [[I2]], ptr [[P2]], align 4 +; CHECK-NEXT: [[I3:%.*]] = call i64 @strtoul(ptr nocapture getelementptr inbounds ([5 x i8], ptr @a5, i64 1, i64 0), ptr null, i32 8) +; CHECK-NEXT: [[P3:%.*]] = getelementptr i64, ptr [[PS]], i64 3 +; CHECK-NEXT: store i64 [[I3]], ptr [[P3]], align 4 +; CHECK-NEXT: [[I4:%.*]] = call i64 @strtoll(ptr nocapture getelementptr inbounds ([5 x i8], ptr @a5, i64 1, i64 0), ptr null, i32 10) +; CHECK-NEXT: [[P4:%.*]] = getelementptr i64, ptr [[PS]], i64 4 +; CHECK-NEXT: store i64 [[I4]], ptr [[P4]], align 4 +; CHECK-NEXT: [[I5:%.*]] = call i64 @strtoul(ptr nocapture getelementptr inbounds ([5 x i8], ptr @a5, i64 1, i64 0), ptr null, i32 16) +; CHECK-NEXT: [[P5:%.*]] = getelementptr i64, ptr [[PS]], i64 5 +; CHECK-NEXT: store i64 [[I5]], ptr [[P5]], align 4 ; CHECK-NEXT: ret void ; - %pa5 = getelementptr [5 x i8], [5 x i8]* @a5, i32 0, i32 5 + %pa5 = getelementptr [5 x i8], ptr @a5, i32 0, i32 5 - %i0 = call i64 @atol(i8* %pa5) - %p0 = getelementptr i64, i64* %ps, i32 0 - store i64 %i0, i64* %p0 + %i0 = call i64 @atol(ptr %pa5) + store i64 %i0, ptr %ps - %i1 = call i64 @atoll(i8* %pa5) - %p1 = getelementptr i64, i64* %ps, i32 1 - store i64 %i1, i64* %p1 + %i1 = call i64 @atoll(ptr %pa5) + %p1 = getelementptr i64, ptr %ps, i32 1 + store i64 %i1, ptr %p1 - %i2 = call i64 @strtol(i8* %pa5, i8** null, i32 0) - %p2 = getelementptr i64, i64* %ps, i32 2 - store i64 %i2, i64* %p2 + %i2 = call i64 @strtol(ptr %pa5, ptr null, i32 0) + %p2 = getelementptr i64, ptr %ps, i32 2 + store i64 %i2, ptr %p2 - %i3 = call i64 @strtoul(i8* %pa5, i8** null, i32 8) - %p3 = getelementptr i64, i64* %ps, i32 3 - store i64 %i3, i64* %p3 + %i3 = call i64 @strtoul(ptr %pa5, ptr null, i32 8) + %p3 = getelementptr i64, ptr %ps, i32 3 + store i64 %i3, ptr %p3 - %i4 = call i64 @strtoll(i8* %pa5, i8** null, i32 10) - %p4 = getelementptr i64, i64* %ps, i32 4 - store i64 %i4, i64* %p4 + %i4 = call i64 @strtoll(ptr %pa5, ptr null, i32 10) + %p4 = getelementptr i64, ptr %ps, i32 4 + store i64 %i4, ptr %p4 - %i5 = call i64 @strtoul(i8* %pa5, i8** null, i32 16) - %p5 = getelementptr i64, i64* %ps, i32 5 - store i64 %i5, i64* %p5 + %i5 = call i64 @strtoul(ptr %pa5, ptr null, i32 16) + %p5 = getelementptr i64, ptr %ps, i32 5 + store i64 %i5, ptr %p5 ret void } @@ -346,23 +333,21 @@ ; Fold sprintf(dst, a5 + 5) to zero, and also ; TODO: fold sprintf(dst, "%s", a5 + 5) to zero. -define void @fold_sprintf_past_end(i32* %pcnt, i8* %dst) { +define void @fold_sprintf_past_end(ptr %pcnt, ptr %dst) { ; CHECK-LABEL: @fold_sprintf_past_end( -; CHECK-NEXT: store i32 0, i32* [[PCNT:%.*]], align 4 -; CHECK-NEXT: [[PN05:%.*]] = getelementptr i32, i32* [[PCNT]], i64 1 -; CHECK-NEXT: store i32 0, i32* [[PN05]], align 4 +; CHECK-NEXT: store i32 0, ptr [[PCNT:%.*]], align 4 +; CHECK-NEXT: [[PN05:%.*]] = getelementptr i32, ptr [[PCNT]], i64 1 +; CHECK-NEXT: store i32 0, ptr [[PN05]], align 4 ; CHECK-NEXT: ret void ; - %p0 = getelementptr [5 x i8], [5 x i8]* @a5, i32 0, i32 0 - %p5 = getelementptr [5 x i8], [5 x i8]* @a5, i32 0, i32 5 + %p5 = getelementptr [5 x i8], ptr @a5, i32 0, i32 5 - %n5_ = call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %p5) - %pn5_ = getelementptr i32, i32* %pcnt, i32 0 - store i32 %n5_, i32* %pn5_ + %n5_ = call i32 (ptr, ptr, ...) @sprintf(ptr %dst, ptr %p5) + store i32 %n5_, ptr %pcnt - %n05 = call i32 (i8*, i8*, ...) @sprintf(i8* %dst, i8* %p0, i8* %p5) - %pn05 = getelementptr i32, i32* %pcnt, i32 1 - store i32 %n05, i32* %pn05 + %n05 = call i32 (ptr, ptr, ...) @sprintf(ptr %dst, ptr @a5, ptr %p5) + %pn05 = getelementptr i32, ptr %pcnt, i32 1 + store i32 %n05, ptr %pn05 ret void } @@ -371,25 +356,23 @@ ; Fold snprintf(dst, n, a5 + 5) to zero, and also ; TODO: fold snprintf(dst, n, "%s", a5 + 5) to zero. -define void @fold_snprintf_past_end(i32* %pcnt, i8* %dst, i64 %n) { +define void @fold_snprintf_past_end(ptr %pcnt, ptr %dst, i64 %n) { ; CHECK-LABEL: @fold_snprintf_past_end( -; CHECK-NEXT: [[N5_:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* [[DST:%.*]], i64 [[N:%.*]], i8* getelementptr inbounds ([5 x i8], [5 x i8]* @a5, i64 1, i64 0)) -; CHECK-NEXT: store i32 [[N5_]], i32* [[PCNT:%.*]], align 4 -; CHECK-NEXT: [[N05:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* [[DST]], i64 [[N]], i8* getelementptr inbounds ([5 x i8], [5 x i8]* @a5, i64 0, i64 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @a5, i64 1, i64 0)) -; CHECK-NEXT: [[PN05:%.*]] = getelementptr i32, i32* [[PCNT]], i64 1 -; CHECK-NEXT: store i32 [[N05]], i32* [[PN05]], align 4 +; CHECK-NEXT: [[N5_:%.*]] = call i32 (ptr, i64, ptr, ...) @snprintf(ptr [[DST:%.*]], i64 [[N:%.*]], ptr getelementptr inbounds ([5 x i8], ptr @a5, i64 1, i64 0)) +; CHECK-NEXT: store i32 [[N5_]], ptr [[PCNT:%.*]], align 4 +; CHECK-NEXT: [[N05:%.*]] = call i32 (ptr, i64, ptr, ...) @snprintf(ptr [[DST]], i64 [[N]], ptr nonnull @a5, ptr getelementptr inbounds ([5 x i8], ptr @a5, i64 1, i64 0)) +; CHECK-NEXT: [[PN05:%.*]] = getelementptr i32, ptr [[PCNT]], i64 1 +; CHECK-NEXT: store i32 [[N05]], ptr [[PN05]], align 4 ; CHECK-NEXT: ret void ; - %p0 = getelementptr [5 x i8], [5 x i8]* @a5, i32 0, i32 0 - %p5 = getelementptr [5 x i8], [5 x i8]* @a5, i32 0, i32 5 + %p5 = getelementptr [5 x i8], ptr @a5, i32 0, i32 5 - %n5_ = call i32 (i8*, i64, i8*, ...) @snprintf(i8* %dst, i64 %n, i8* %p5) - %pn5_ = getelementptr i32, i32* %pcnt, i32 0 - store i32 %n5_, i32* %pn5_ + %n5_ = call i32 (ptr, i64, ptr, ...) @snprintf(ptr %dst, i64 %n, ptr %p5) + store i32 %n5_, ptr %pcnt - %n05 = call i32 (i8*, i64, i8*, ...) @snprintf(i8* %dst, i64 %n, i8* %p0, i8* %p5) - %pn05 = getelementptr i32, i32* %pcnt, i32 1 - store i32 %n05, i32* %pn05 + %n05 = call i32 (ptr, i64, ptr, ...) @snprintf(ptr %dst, i64 %n, ptr @a5, ptr %p5) + %pn05 = getelementptr i32, ptr %pcnt, i32 1 + store i32 %n05, ptr %pn05 ret void } diff --git a/llvm/test/Transforms/InstCombine/strchr-1.ll b/llvm/test/Transforms/InstCombine/strchr-1.ll --- a/llvm/test/Transforms/InstCombine/strchr-1.ll +++ b/llvm/test/Transforms/InstCombine/strchr-1.ll @@ -7,82 +7,77 @@ @hello = constant [14 x i8] c"hello world\5Cn\00" @null = constant [1 x i8] zeroinitializer @newlines = constant [3 x i8] c"\0D\0A\00" -@chp = global i8* zeroinitializer +@chp = global ptr zeroinitializer -declare i8* @strchr(i8*, i32) +declare ptr @strchr(ptr, i32) define void @test_simplify1() { ; CHECK-LABEL: @test_simplify1( -; CHECK-NEXT: store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 6), i8** @chp, align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([14 x i8], ptr @hello, i32 0, i32 6), ptr @chp, align 4 ; CHECK-NEXT: ret void ; - %str = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0 - %dst = call i8* @strchr(i8* %str, i32 119) - store i8* %dst, i8** @chp + %dst = call ptr @strchr(ptr @hello, i32 119) + store ptr %dst, ptr @chp ret void } define void @test_simplify2() { ; CHECK-LABEL: @test_simplify2( -; CHECK-NEXT: store i8* null, i8** @chp, align 4 +; CHECK-NEXT: store ptr null, ptr @chp, align 4 ; CHECK-NEXT: ret void ; - %str = getelementptr [1 x i8], [1 x i8]* @null, i32 0, i32 0 - %dst = call i8* @strchr(i8* %str, i32 119) - store i8* %dst, i8** @chp + %dst = call ptr @strchr(ptr @null, i32 119) + store ptr %dst, ptr @chp ret void } define void @test_simplify3() { ; CHECK-LABEL: @test_simplify3( -; CHECK-NEXT: store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 13), i8** @chp, align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([14 x i8], ptr @hello, i32 0, i32 13), ptr @chp, align 4 ; CHECK-NEXT: ret void ; - %src = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0 - %dst = call i8* @strchr(i8* %src, i32 0) - store i8* %dst, i8** @chp + %dst = call ptr @strchr(ptr @hello, i32 0) + store ptr %dst, ptr @chp ret void } define void @test_simplify4(i32 %chr) { ; CHECK-LABEL: @test_simplify4( -; CHECK-NEXT: [[MEMCHR:%.*]] = call i8* @memchr(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 0), i32 [[CHR:%.*]], i32 14) -; CHECK-NEXT: store i8* [[MEMCHR]], i8** @chp, align 4 +; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @memchr(ptr noundef nonnull @hello, i32 [[CHR:%.*]], i32 14) +; CHECK-NEXT: store ptr [[MEMCHR]], ptr @chp, align 4 ; CHECK-NEXT: ret void ; - %src = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0 - %dst = call i8* @strchr(i8* %src, i32 %chr) - store i8* %dst, i8** @chp + %dst = call ptr @strchr(ptr @hello, i32 %chr) + store ptr %dst, ptr @chp ret void } define void @test_simplify5() { ; CHECK-LABEL: @test_simplify5( -; CHECK-NEXT: store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @hello, i32 0, i32 13), i8** @chp, align 4 +; CHECK-NEXT: store ptr getelementptr inbounds ([14 x i8], ptr @hello, i32 0, i32 13), ptr @chp, align 4 ; CHECK-NEXT: ret void ; - %src = getelementptr [14 x i8], [14 x i8]* @hello, i32 0, i32 0 - %dst = call i8* @strchr(i8* %src, i32 65280) - store i8* %dst, i8** @chp + %dst = call ptr @strchr(ptr @hello, i32 65280) + store ptr %dst, ptr @chp ret void } ; Check transformation strchr(p, 0) -> p + strlen(p) -define void @test_simplify6(i8* %str) { +define void @test_simplify6(ptr %str) { ; CHECK-LABEL: @test_simplify6( -; CHECK-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* noundef nonnull dereferenceable(1) [[STR:%.*]]) -; CHECK-NEXT: [[STRCHR:%.*]] = getelementptr inbounds i8, i8* [[STR]], i32 [[STRLEN]] -; CHECK-NEXT: store i8* [[STRCHR]], i8** @chp, align 4 +; CHECK-NEXT: [[STRLEN:%.*]] = call i32 @strlen(ptr noundef nonnull dereferenceable(1) [[STR:%.*]]) +; CHECK-NEXT: [[STRCHR:%.*]] = getelementptr inbounds i8, ptr [[STR]], i32 [[STRLEN]] +; CHECK-NEXT: store ptr [[STRCHR]], ptr @chp, align 4 ; CHECK-NEXT: ret void ; - %dst = call i8* @strchr(i8* %str, i32 0) - store i8* %dst, i8** @chp + %dst = call ptr @strchr(ptr %str, i32 0) + store ptr %dst, ptr @chp ret void } @@ -99,27 +94,27 @@ ; CHECK-NEXT: ret i1 [[MEMCHR1]] ; - %dst = call i8* @strchr(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @newlines, i64 0, i64 0), i32 %C) - %cmp = icmp ne i8* %dst, null + %dst = call ptr @strchr(ptr @newlines, i32 %C) + %cmp = icmp ne ptr %dst, null ret i1 %cmp } -define i8* @test1(i8* %str, i32 %c) { +define ptr @test1(ptr %str, i32 %c) { ; CHECK-LABEL: @test1( -; CHECK-NEXT: [[RET:%.*]] = call i8* @strchr(i8* noundef nonnull dereferenceable(1) [[STR:%.*]], i32 [[C:%.*]]) -; CHECK-NEXT: ret i8* [[RET]] +; CHECK-NEXT: [[RET:%.*]] = call ptr @strchr(ptr noundef nonnull dereferenceable(1) [[STR:%.*]], i32 [[C:%.*]]) +; CHECK-NEXT: ret ptr [[RET]] ; - %ret = call i8* @strchr(i8* %str, i32 %c) - ret i8* %ret + %ret = call ptr @strchr(ptr %str, i32 %c) + ret ptr %ret } -define i8* @test2(i8* %str, i32 %c) null_pointer_is_valid { +define ptr @test2(ptr %str, i32 %c) null_pointer_is_valid { ; CHECK-LABEL: @test2( -; CHECK-NEXT: [[RET:%.*]] = call i8* @strchr(i8* noundef [[STR:%.*]], i32 [[C:%.*]]) -; CHECK-NEXT: ret i8* [[RET]] +; CHECK-NEXT: [[RET:%.*]] = call ptr @strchr(ptr noundef [[STR:%.*]], i32 [[C:%.*]]) +; CHECK-NEXT: ret ptr [[RET]] ; - %ret = call i8* @strchr(i8* %str, i32 %c) - ret i8* %ret + %ret = call ptr @strchr(ptr %str, i32 %c) + ret ptr %ret } diff --git a/llvm/test/Transforms/InstCombine/strchr-3.ll b/llvm/test/Transforms/InstCombine/strchr-3.ll --- a/llvm/test/Transforms/InstCombine/strchr-3.ll +++ b/llvm/test/Transforms/InstCombine/strchr-3.ll @@ -11,119 +11,113 @@ @s11102 = constant [6 x i8] c"\01\01\01\00\02\00" @s21111 = constant [6 x i8] c"\02\01\01\01\01\00" -declare i8* @strchr(i8*, i32) +declare ptr @strchr(ptr, i32) ; Fold strchr(S = "\01", C) to C == '\01' ? S : C == '\0' ? S + 1 : null. -define i8* @fold_strchr_s1_C(i32 %C) { +define ptr @fold_strchr_s1_C(i32 %C) { ; CHECK-LABEL: @fold_strchr_s1_C( ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[C:%.*]] to i8 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 0 -; CHECK-NEXT: [[MEMCHR_SEL1:%.*]] = select i1 [[TMP2]], i8* getelementptr inbounds ([2 x i8], [2 x i8]* @s1, i64 0, i64 1), i8* null +; CHECK-NEXT: [[MEMCHR_SEL1:%.*]] = select i1 [[TMP2]], ptr getelementptr inbounds ([2 x i8], ptr @s1, i64 0, i64 1), ptr null ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP1]], 1 -; CHECK-NEXT: [[MEMCHR_SEL2:%.*]] = select i1 [[TMP3]], i8* getelementptr inbounds ([2 x i8], [2 x i8]* @s1, i64 0, i64 0), i8* [[MEMCHR_SEL1]] -; CHECK-NEXT: ret i8* [[MEMCHR_SEL2]] +; CHECK-NEXT: [[MEMCHR_SEL2:%.*]] = select i1 [[TMP3]], ptr @s1, ptr [[MEMCHR_SEL1]] +; CHECK-NEXT: ret ptr [[MEMCHR_SEL2]] ; - %ptr = getelementptr inbounds [2 x i8], [2 x i8]* @s1, i64 0, i64 0 - %ret = call i8* @strchr(i8* %ptr, i32 %C) - ret i8* %ret + %ret = call ptr @strchr(ptr @s1, i32 %C) + ret ptr %ret } ; Fold strchr(S = "\01\01", C) to C == '\01' ? S : C == '\0' ? S + 2 : null. -define i8* @fold_strchr_s11_C(i32 %C) { +define ptr @fold_strchr_s11_C(i32 %C) { ; CHECK-LABEL: @fold_strchr_s11_C( ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[C:%.*]] to i8 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 0 -; CHECK-NEXT: [[MEMCHR_SEL1:%.*]] = select i1 [[TMP2]], i8* getelementptr inbounds ([3 x i8], [3 x i8]* @s11, i64 0, i64 2), i8* null +; CHECK-NEXT: [[MEMCHR_SEL1:%.*]] = select i1 [[TMP2]], ptr getelementptr inbounds ([3 x i8], ptr @s11, i64 0, i64 2), ptr null ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP1]], 1 -; CHECK-NEXT: [[MEMCHR_SEL2:%.*]] = select i1 [[TMP3]], i8* getelementptr inbounds ([3 x i8], [3 x i8]* @s11, i64 0, i64 0), i8* [[MEMCHR_SEL1]] -; CHECK-NEXT: ret i8* [[MEMCHR_SEL2]] +; CHECK-NEXT: [[MEMCHR_SEL2:%.*]] = select i1 [[TMP3]], ptr @s11, ptr [[MEMCHR_SEL1]] +; CHECK-NEXT: ret ptr [[MEMCHR_SEL2]] ; - %ptr = getelementptr inbounds [3 x i8], [3 x i8]* @s11, i64 0, i64 0 - %ret = call i8* @strchr(i8* %ptr, i32 %C) - ret i8* %ret + %ret = call ptr @strchr(ptr @s11, i32 %C) + ret ptr %ret } ; Fold strchr(S = "\01\01\01", C) to C == '\01' ? S : C == '\0' ? S + 3 : null. -define i8* @fold_strchr_s111_C(i32 %C) { +define ptr @fold_strchr_s111_C(i32 %C) { ; CHECK-LABEL: @fold_strchr_s111_C( ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[C:%.*]] to i8 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 0 -; CHECK-NEXT: [[MEMCHR_SEL1:%.*]] = select i1 [[TMP2]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @s111, i64 0, i64 3), i8* null +; CHECK-NEXT: [[MEMCHR_SEL1:%.*]] = select i1 [[TMP2]], ptr getelementptr inbounds ([4 x i8], ptr @s111, i64 0, i64 3), ptr null ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP1]], 1 -; CHECK-NEXT: [[MEMCHR_SEL2:%.*]] = select i1 [[TMP3]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @s111, i64 0, i64 0), i8* [[MEMCHR_SEL1]] -; CHECK-NEXT: ret i8* [[MEMCHR_SEL2]] +; CHECK-NEXT: [[MEMCHR_SEL2:%.*]] = select i1 [[TMP3]], ptr @s111, ptr [[MEMCHR_SEL1]] +; CHECK-NEXT: ret ptr [[MEMCHR_SEL2]] ; - %ptr = getelementptr inbounds [4 x i8], [4 x i8]* @s111, i64 0, i64 0 - %ret = call i8* @strchr(i8* %ptr, i32 %C) - ret i8* %ret + %ret = call ptr @strchr(ptr @s111, i32 %C) + ret ptr %ret } ; Fold strchr(S = "\00\00\00", C) to C == '\0' ? S : null. -define i8* @fold_strchr_s000_C(i32 %C) { +define ptr @fold_strchr_s000_C(i32 %C) { ; CHECK-LABEL: @fold_strchr_s000_C( ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[C:%.*]] to i8 ; CHECK-NEXT: [[MEMCHR_CHAR0CMP:%.*]] = icmp eq i8 [[TMP1]], 0 -; CHECK-NEXT: [[MEMCHR_SEL:%.*]] = select i1 [[MEMCHR_CHAR0CMP]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @s000, i64 0, i64 0), i8* null -; CHECK-NEXT: ret i8* [[MEMCHR_SEL]] +; CHECK-NEXT: [[MEMCHR_SEL:%.*]] = select i1 [[MEMCHR_CHAR0CMP]], ptr @s000, ptr null +; CHECK-NEXT: ret ptr [[MEMCHR_SEL]] ; - %ptr = getelementptr inbounds [4 x i8], [4 x i8]* @s000, i64 0, i64 0 - %ret = call i8* @strchr(i8* %ptr, i32 %C) - ret i8* %ret + %ret = call ptr @strchr(ptr @s000, i32 %C) + ret ptr %ret } ; Do not fold strchr(S = "\02\01\01\01\01", C). It's transformed to ; memchr(S, C, 6). -define i8* @xform_strchr_s21111_C(i32 %C) { +define ptr @xform_strchr_s21111_C(i32 %C) { ; CHECK-LABEL: @xform_strchr_s21111_C( -; CHECK-NEXT: [[MEMCHR:%.*]] = call i8* @memchr(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([6 x i8], [6 x i8]* @s21111, i64 0, i64 0), i32 [[C:%.*]], i64 6) -; CHECK-NEXT: ret i8* [[MEMCHR]] +; CHECK-NEXT: [[MEMCHR:%.*]] = call ptr @memchr(ptr noundef nonnull @s21111, i32 [[C:%.*]], i64 6) +; CHECK-NEXT: ret ptr [[MEMCHR]] ; - %ptr = getelementptr inbounds [6 x i8], [6 x i8]* @s21111, i64 0, i64 0 - %ret = call i8* @strchr(i8* %ptr, i32 %C) - ret i8* %ret + %ret = call ptr @strchr(ptr @s21111, i32 %C) + ret ptr %ret } ; Fold strchr(S = "\02\01\01\01\01" + 1, C) to ; C == '\01' ? S + 1 : C == '\0' ? S + 5 : null. -define i8* @fold_strchr_s21111p1_C(i32 %C) { +define ptr @fold_strchr_s21111p1_C(i32 %C) { ; CHECK-LABEL: @fold_strchr_s21111p1_C( ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[C:%.*]] to i8 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 0 -; CHECK-NEXT: [[MEMCHR_SEL1:%.*]] = select i1 [[TMP2]], i8* getelementptr inbounds ([6 x i8], [6 x i8]* @s21111, i64 0, i64 5), i8* null +; CHECK-NEXT: [[MEMCHR_SEL1:%.*]] = select i1 [[TMP2]], ptr getelementptr inbounds ([6 x i8], ptr @s21111, i64 0, i64 5), ptr null ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP1]], 1 -; CHECK-NEXT: [[MEMCHR_SEL2:%.*]] = select i1 [[TMP3]], i8* getelementptr inbounds ([6 x i8], [6 x i8]* @s21111, i64 0, i64 1), i8* [[MEMCHR_SEL1]] -; CHECK-NEXT: ret i8* [[MEMCHR_SEL2]] +; CHECK-NEXT: [[MEMCHR_SEL2:%.*]] = select i1 [[TMP3]], ptr getelementptr inbounds ([6 x i8], ptr @s21111, i64 0, i64 1), ptr [[MEMCHR_SEL1]] +; CHECK-NEXT: ret ptr [[MEMCHR_SEL2]] ; - %ptr = getelementptr inbounds [6 x i8], [6 x i8]* @s21111, i64 0, i64 1 - %ret = call i8* @strchr(i8* %ptr, i32 %C) - ret i8* %ret + %ptr = getelementptr inbounds [6 x i8], ptr @s21111, i64 0, i64 1 + %ret = call ptr @strchr(ptr %ptr, i32 %C) + ret ptr %ret } ; Fold strchr(S = "\01\01\01\00\02", C) to ; C == '\01' ? S : C == '\0' ? S + 3 : null. -define i8* @fold_strchr_s11102_C(i32 %C) { +define ptr @fold_strchr_s11102_C(i32 %C) { ; CHECK-LABEL: @fold_strchr_s11102_C( ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[C:%.*]] to i8 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 0 -; CHECK-NEXT: [[MEMCHR_SEL1:%.*]] = select i1 [[TMP2]], i8* getelementptr inbounds ([6 x i8], [6 x i8]* @s11102, i64 0, i64 3), i8* null +; CHECK-NEXT: [[MEMCHR_SEL1:%.*]] = select i1 [[TMP2]], ptr getelementptr inbounds ([6 x i8], ptr @s11102, i64 0, i64 3), ptr null ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP1]], 1 -; CHECK-NEXT: [[MEMCHR_SEL2:%.*]] = select i1 [[TMP3]], i8* getelementptr inbounds ([6 x i8], [6 x i8]* @s11102, i64 0, i64 0), i8* [[MEMCHR_SEL1]] -; CHECK-NEXT: ret i8* [[MEMCHR_SEL2]] +; CHECK-NEXT: [[MEMCHR_SEL2:%.*]] = select i1 [[TMP3]], ptr @s11102, ptr [[MEMCHR_SEL1]] +; CHECK-NEXT: ret ptr [[MEMCHR_SEL2]] ; - %ptr = getelementptr inbounds [6 x i8], [6 x i8]* @s11102, i64 0, i64 0 - %ret = call i8* @strchr(i8* %ptr, i32 %C) - ret i8* %ret + %ret = call ptr @strchr(ptr @s11102, i32 %C) + ret ptr %ret } diff --git a/llvm/test/Transforms/InstCombine/strcmp-memcmp.ll b/llvm/test/Transforms/InstCombine/strcmp-memcmp.ll --- a/llvm/test/Transforms/InstCombine/strcmp-memcmp.ll +++ b/llvm/test/Transforms/InstCombine/strcmp-memcmp.ll @@ -8,553 +8,485 @@ declare void @use(i32) -define i32 @strcmp_memcmp([12 x i8]* dereferenceable (12) %buf) nofree nosync { +define i32 @strcmp_memcmp(ptr dereferenceable (12) %buf) nofree nosync { ; CHECK-LABEL: @strcmp_memcmp( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(4) [[STRING]], i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key, i64 4) ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0)) + %call = call i32 @strcmp(ptr nonnull %buf, ptr @key) %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv } -declare i32 @strcmp(i8* nocapture, i8* nocapture) +declare i32 @strcmp(ptr nocapture, ptr nocapture) -define i32 @strcmp_memcmp2([12 x i8]* dereferenceable (12) %buf) nofree nosync { +define i32 @strcmp_memcmp2(ptr dereferenceable (12) %buf) nofree nosync { ; CHECK-LABEL: @strcmp_memcmp2( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* noundef nonnull dereferenceable(4) [[STRING]], i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], i64 4) ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string) + %call = call i32 @strcmp(ptr @key, ptr nonnull %buf) %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv } -define i32 @strcmp_memcmp3([12 x i8]* dereferenceable (12) %buf) nofree nosync { +define i32 @strcmp_memcmp3(ptr dereferenceable (12) %buf) nofree nosync { ; CHECK-LABEL: @strcmp_memcmp3( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(4) [[STRING]], i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key, i64 4) ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0)) + %call = call i32 @strcmp(ptr nonnull %buf, ptr @key) %cmp = icmp ne i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv } -define i32 @strcmp_memcmp4([12 x i8]* dereferenceable (12) %buf) nofree nosync { +define i32 @strcmp_memcmp4(ptr dereferenceable (12) %buf) nofree nosync { ; CHECK-LABEL: @strcmp_memcmp4( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* noundef nonnull dereferenceable(4) [[STRING]], i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], i64 4) ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string) + %call = call i32 @strcmp(ptr @key, ptr nonnull %buf) %cmp = icmp ne i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv } -define i32 @strcmp_memcmp5([5 x i8]* dereferenceable (5) %buf) nofree nosync { +define i32 @strcmp_memcmp5(ptr dereferenceable (5) %buf) nofree nosync { ; CHECK-LABEL: @strcmp_memcmp5( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [5 x i8], [5 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(4) [[STRING]], i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key, i64 4) ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %string = getelementptr inbounds [5 x i8], [5 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strcmp(i8* nonnull align 1 %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0)) + %call = call i32 @strcmp(ptr nonnull align 1 %buf, ptr @key) %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv } -define i32 @strcmp_memcmp6([12 x i8]* dereferenceable (12) %buf) nofree nosync { +define i32 @strcmp_memcmp6(ptr dereferenceable (12) %buf) nofree nosync { ; CHECK-LABEL: @strcmp_memcmp6( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(4) [[STRING]], i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key, i64 4) ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0)) + %call = call i32 @strcmp(ptr nonnull %buf, ptr @key) %cmp = icmp sgt i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv } -define i32 @strcmp_memcmp7([12 x i8]* dereferenceable (12) %buf) nofree nosync { +define i32 @strcmp_memcmp7(ptr dereferenceable (12) %buf) nofree nosync { ; CHECK-LABEL: @strcmp_memcmp7( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* noundef nonnull dereferenceable(4) [[STRING]], i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], i64 4) ; CHECK-NEXT: [[MEMCMP_LOBIT:%.*]] = lshr i32 [[MEMCMP]], 31 ; CHECK-NEXT: ret i32 [[MEMCMP_LOBIT]] ; - %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string) + %call = call i32 @strcmp(ptr @key, ptr nonnull %buf) %cmp = icmp slt i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv } -define i32 @strcmp_memcmp8([4 x i8]* dereferenceable (4) %buf) nofree nosync { +define i32 @strcmp_memcmp8(ptr dereferenceable (4) %buf) nofree nosync { ; CHECK-LABEL: @strcmp_memcmp8( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(4) [[STRING]], i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key, i64 4) ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %string = getelementptr inbounds [4 x i8], [4 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0)) + %call = call i32 @strcmp(ptr nonnull %buf, ptr @key) %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv } -define i32 @strcmp_memcmp9([12 x i8]* dereferenceable (12) %buf) nofree nosync { +define i32 @strcmp_memcmp9(ptr dereferenceable (12) %buf) nofree nosync { ; CHECK-LABEL: @strcmp_memcmp9( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(4) [[STRING]], i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([8 x i8], [8 x i8]* @abc, i64 0, i64 0), i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @abc, i64 4) ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @abc, i64 0, i64 0)) + %call = call i32 @strcmp(ptr nonnull %buf, ptr @abc) %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv } -define i32 @strncmp_memcmp([12 x i8]* dereferenceable (12) %buf) nofree nosync { +define i32 @strncmp_memcmp(ptr dereferenceable (12) %buf) nofree nosync { ; CHECK-LABEL: @strncmp_memcmp( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(2) [[STRING]], i8* noundef nonnull dereferenceable(2) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 2) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(2) [[BUF:%.*]], ptr noundef nonnull dereferenceable(2) @key, i64 2) ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 2) + %call = call i32 @strncmp(ptr nonnull %buf, ptr @key, i64 2) %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv } -declare i32 @strncmp(i8* nocapture, i8* nocapture, i64) +declare i32 @strncmp(ptr nocapture, ptr nocapture, i64) -define i32 @strncmp_memcmp2([12 x i8]* dereferenceable (12) %buf) nofree nosync { +define i32 @strncmp_memcmp2(ptr dereferenceable (12) %buf) nofree nosync { ; CHECK-LABEL: @strncmp_memcmp2( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(4) [[STRING]], i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key, i64 4) ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 11) + %call = call i32 @strncmp(ptr nonnull %buf, ptr @key, i64 11) %cmp = icmp ne i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv } -define i32 @strncmp_memcmp3([12 x i8]* dereferenceable (12) %buf) nofree nosync { +define i32 @strncmp_memcmp3(ptr dereferenceable (12) %buf) nofree nosync { ; CHECK-LABEL: @strncmp_memcmp3( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* noundef nonnull dereferenceable(4) [[STRING]], i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], i64 4) ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 11) + %call = call i32 @strncmp(ptr @key, ptr nonnull %buf, i64 11) %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv } -define i32 @strncmp_memcmp4([12 x i8]* dereferenceable (12) %buf) nofree nosync { +define i32 @strncmp_memcmp4(ptr dereferenceable (12) %buf) nofree nosync { ; CHECK-LABEL: @strncmp_memcmp4( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(4) [[STRING]], i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key, i64 4) ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 5) + %call = call i32 @strncmp(ptr nonnull %buf, ptr @key, i64 5) %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv } -define i32 @strncmp_memcmp5([12 x i8]* dereferenceable (12) %buf) nofree nosync { +define i32 @strncmp_memcmp5(ptr dereferenceable (12) %buf) nofree nosync { ; CHECK-LABEL: @strncmp_memcmp5( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* noundef nonnull dereferenceable(4) [[STRING]], i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], i64 4) ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 5) + %call = call i32 @strncmp(ptr @key, ptr nonnull %buf, i64 5) %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv } -define i32 @strncmp_memcmp6([12 x i8]* dereferenceable (12) %buf) nofree nosync { +define i32 @strncmp_memcmp6(ptr dereferenceable (12) %buf) nofree nosync { ; CHECK-LABEL: @strncmp_memcmp6( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* noundef nonnull dereferenceable(4) [[STRING]], i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], i64 4) ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 5) + %call = call i32 @strncmp(ptr @key, ptr nonnull %buf, i64 5) %cmp = icmp ne i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv } -define i32 @strncmp_memcmp7([12 x i8]* dereferenceable (12) %buf) nofree nosync { +define i32 @strncmp_memcmp7(ptr dereferenceable (12) %buf) nofree nosync { ; CHECK-LABEL: @strncmp_memcmp7( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(4) [[STRING]], i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key, i64 4) ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4) + %call = call i32 @strncmp(ptr nonnull %buf, ptr @key, i64 4) %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv } -define i32 @strncmp_memcmp8([12 x i8]* dereferenceable (12) %buf) nofree nosync { +define i32 @strncmp_memcmp8(ptr dereferenceable (12) %buf) nofree nosync { ; CHECK-LABEL: @strncmp_memcmp8( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(3) [[STRING]], i8* noundef nonnull dereferenceable(3) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 3) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(3) [[BUF:%.*]], ptr noundef nonnull dereferenceable(3) @key, i64 3) ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 3) + %call = call i32 @strncmp(ptr nonnull %buf, ptr @key, i64 3) %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv } -define i32 @strncmp_memcmp9([12 x i8]* dereferenceable (12) %buf) nofree nosync { +define i32 @strncmp_memcmp9(ptr dereferenceable (12) %buf) nofree nosync { ; CHECK-LABEL: @strncmp_memcmp9( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* noundef nonnull dereferenceable(4) [[STRING]], i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], i64 4) ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 5) + %call = call i32 @strncmp(ptr @key, ptr nonnull %buf, i64 5) %cmp = icmp sgt i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv } -define i32 @strncmp_memcmp10([12 x i8]* dereferenceable (12) %buf) nofree nosync { +define i32 @strncmp_memcmp10(ptr dereferenceable (12) %buf) nofree nosync { ; CHECK-LABEL: @strncmp_memcmp10( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* noundef nonnull dereferenceable(4) [[STRING]], i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], i64 4) ; CHECK-NEXT: [[MEMCMP_LOBIT:%.*]] = lshr i32 [[MEMCMP]], 31 ; CHECK-NEXT: ret i32 [[MEMCMP_LOBIT]] ; - %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 5) + %call = call i32 @strncmp(ptr @key, ptr nonnull %buf, i64 5) %cmp = icmp slt i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv } -define i32 @strncmp_memcmp11([12 x i8]* dereferenceable (12) %buf) nofree nosync { +define i32 @strncmp_memcmp11(ptr dereferenceable (12) %buf) nofree nosync { ; CHECK-LABEL: @strncmp_memcmp11( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* noundef nonnull dereferenceable(4) [[STRING]], i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], i64 4) ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 12) + %call = call i32 @strncmp(ptr @key, ptr nonnull %buf, i64 12) %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv } -define i32 @strncmp_memcmp12([12 x i8]* dereferenceable (12) %buf) nofree nosync { +define i32 @strncmp_memcmp12(ptr dereferenceable (12) %buf) nofree nosync { ; CHECK-LABEL: @strncmp_memcmp12( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* noundef nonnull dereferenceable(4) [[STRING]], i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], i64 4) ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 12) + %call = call i32 @strncmp(ptr @key, ptr nonnull %buf, i64 12) %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv } -define i32 @strncmp_memcmp13([12 x i8]* dereferenceable (12) %buf) nofree nosync { +define i32 @strncmp_memcmp13(ptr dereferenceable (12) %buf) nofree nosync { ; CHECK-LABEL: @strncmp_memcmp13( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(2) [[STRING]], i8* noundef nonnull dereferenceable(2) getelementptr inbounds ([8 x i8], [8 x i8]* @abc, i64 0, i64 0), i64 2) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(2) [[BUF:%.*]], ptr noundef nonnull dereferenceable(2) @abc, i64 2) ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* nonnull %string, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @abc, i64 0, i64 0), i64 2) + %call = call i32 @strncmp(ptr nonnull %buf, ptr @abc, i64 2) %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv } -define i32 @strncmp_memcmp14([12 x i8]* dereferenceable (12) %buf) nofree nosync { +define i32 @strncmp_memcmp14(ptr dereferenceable (12) %buf) nofree nosync { ; CHECK-LABEL: @strncmp_memcmp14( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* noundef nonnull dereferenceable(4) [[STRING]], i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([8 x i8], [8 x i8]* @abc, i64 0, i64 0), i64 4) +; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(ptr noundef nonnull dereferenceable(4) [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @abc, i64 4) ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* nonnull %string, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @abc, i64 0, i64 0), i64 12) + %call = call i32 @strncmp(ptr nonnull %buf, ptr @abc, i64 12) %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv } ; Negative tests -define i32 @strcmp_memcmp_bad([12 x i8]* dereferenceable (12) %buf) nofree nosync { +define i32 @strcmp_memcmp_bad(ptr dereferenceable (12) %buf) nofree nosync { ; CHECK-LABEL: @strcmp_memcmp_bad( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(i8* noundef nonnull [[STRING]], i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0)) +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr noundef nonnull [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key) ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CALL]], 3 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0)) + %call = call i32 @strcmp(ptr nonnull %buf, ptr @key) %cmp = icmp sgt i32 %call, 3 %conv = zext i1 %cmp to i32 ret i32 %conv } -define i32 @strcmp_memcmp_bad2([12 x i8]* dereferenceable (12) %buf) nofree nosync { +define i32 @strcmp_memcmp_bad2(ptr dereferenceable (12) %buf) nofree nosync { ; CHECK-LABEL: @strcmp_memcmp_bad2( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* noundef nonnull [[STRING]]) +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull [[BUF:%.*]]) ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[CALL]], 3 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string) + %call = call i32 @strcmp(ptr @key, ptr nonnull %buf) %cmp = icmp slt i32 %call, 3 %conv = zext i1 %cmp to i32 ret i32 %conv } -define i32 @strcmp_memcmp_bad3([12 x i8]* dereferenceable (12) %buf) nofree nosync { +define i32 @strcmp_memcmp_bad3(ptr dereferenceable (12) %buf) nofree nosync { ; CHECK-LABEL: @strcmp_memcmp_bad3( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(i8* noundef nonnull [[STRING]], i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0)) +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr noundef nonnull [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key) ; CHECK-NEXT: ret i32 [[CALL]] ; - %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0)) + %call = call i32 @strcmp(ptr nonnull %buf, ptr @key) ret i32 %call } -define i32 @strcmp_memcmp_bad4(i8* nocapture readonly %buf) nofree nosync { +define i32 @strcmp_memcmp_bad4(ptr nocapture readonly %buf) nofree nosync { ; CHECK-LABEL: @strcmp_memcmp_bad4( -; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @strcmp(i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* noundef nonnull dereferenceable(1) [[BUF:%.*]]) +; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @strcmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(1) [[BUF:%.*]]) ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %call = tail call i32 @strcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* %buf) + %call = tail call i32 @strcmp(ptr @key, ptr %buf) %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv } -define i32 @strcmp_memcmp_bad5([3 x i8]* dereferenceable (3) %buf) nofree nosync { +define i32 @strcmp_memcmp_bad5(ptr dereferenceable (3) %buf) nofree nosync { ; CHECK-LABEL: @strcmp_memcmp_bad5( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [3 x i8], [3 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(i8* noundef nonnull [[STRING]], i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0)) +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr noundef nonnull [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key) ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %string = getelementptr inbounds [3 x i8], [3 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0)) + %call = call i32 @strcmp(ptr nonnull %buf, ptr @key) %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv } -define i32 @strcmp_memcmp_bad6([4 x i8]* dereferenceable (4) %buf, i8* nocapture readonly %k) nofree nosync { +define i32 @strcmp_memcmp_bad6(ptr dereferenceable (4) %buf, ptr nocapture readonly %k) nofree nosync { ; CHECK-LABEL: @strcmp_memcmp_bad6( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(i8* noundef nonnull [[STRING]], i8* noundef nonnull dereferenceable(1) [[K:%.*]]) +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr noundef nonnull [[BUF:%.*]], ptr noundef nonnull dereferenceable(1) [[K:%.*]]) ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %string = getelementptr inbounds [4 x i8], [4 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strcmp(i8* nonnull %string, i8* %k) + %call = call i32 @strcmp(ptr nonnull %buf, ptr %k) %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv } -define i32 @strcmp_memcmp_bad7(i8* nocapture readonly %k) nofree nosync { +define i32 @strcmp_memcmp_bad7(ptr nocapture readonly %k) nofree nosync { ; CHECK-LABEL: @strcmp_memcmp_bad7( -; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @strcmp(i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* noundef nonnull dereferenceable(1) [[K:%.*]]) +; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @strcmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(1) [[K:%.*]]) ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %call = tail call i32 @strcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* %k) + %call = tail call i32 @strcmp(ptr @key, ptr %k) %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv } -define i32 @strcmp_memcmp_bad8([4 x i8]* dereferenceable (4) %buf) nofree nosync { +define i32 @strcmp_memcmp_bad8(ptr dereferenceable (4) %buf) nofree nosync { ; CHECK-LABEL: @strcmp_memcmp_bad8( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(i8* noundef nonnull [[STRING]], i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0)) +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr noundef nonnull [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key) ; CHECK-NEXT: tail call void @use(i32 [[CALL]]) ; CHECK-NEXT: ret i32 0 ; - %string = getelementptr inbounds [4 x i8], [4 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0)) + %call = call i32 @strcmp(ptr nonnull %buf, ptr @key) tail call void @use(i32 %call) ret i32 0 } -define i32 @strncmp_memcmp_bad([12 x i8]* dereferenceable (12) %buf) nofree nosync { +define i32 @strncmp_memcmp_bad(ptr dereferenceable (12) %buf) nofree nosync { ; CHECK-LABEL: @strncmp_memcmp_bad( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[CALL:%.*]] = call i32 @strncmp(i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* noundef nonnull [[STRING]], i64 5) +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strncmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull [[BUF:%.*]], i64 5) ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CALL]], 3 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 5) + %call = call i32 @strncmp(ptr @key, ptr nonnull %buf, i64 5) %cmp = icmp sgt i32 %call, 3 %conv = zext i1 %cmp to i32 ret i32 %conv } -define i32 @strncmp_memcmp_bad1([12 x i8]* dereferenceable (12) %buf) nofree nosync { +define i32 @strncmp_memcmp_bad1(ptr dereferenceable (12) %buf) nofree nosync { ; CHECK-LABEL: @strncmp_memcmp_bad1( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[CALL:%.*]] = call i32 @strncmp(i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* noundef nonnull [[STRING]], i64 5) +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strncmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull [[BUF:%.*]], i64 5) ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[CALL]], 3 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 5) + %call = call i32 @strncmp(ptr @key, ptr nonnull %buf, i64 5) %cmp = icmp slt i32 %call, 3 %conv = zext i1 %cmp to i32 ret i32 %conv } -define i32 @strncmp_memcmp_bad2([12 x i8]* dereferenceable (12) %buf, i64 %n) nofree nosync { +define i32 @strncmp_memcmp_bad2(ptr dereferenceable (12) %buf, i64 %n) nofree nosync { ; CHECK-LABEL: @strncmp_memcmp_bad2( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[CALL:%.*]] = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull [[STRING]], i64 [[N:%.*]]) +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strncmp(ptr nonnull @key, ptr nonnull [[BUF:%.*]], i64 [[N:%.*]]) ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[CALL]], 1 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull %string, i64 %n) + %call = call i32 @strncmp(ptr @key, ptr nonnull %buf, i64 %n) %cmp = icmp slt i32 %call, 1 %conv = zext i1 %cmp to i32 ret i32 %conv } -define i32 @strncmp_memcmp_bad3(i8* nocapture readonly %k) nofree nosync { +define i32 @strncmp_memcmp_bad3(ptr nocapture readonly %k) nofree nosync { ; CHECK-LABEL: @strncmp_memcmp_bad3( -; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @strncmp(i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* noundef nonnull dereferenceable(1) [[K:%.*]], i64 2) +; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @strncmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(1) [[K:%.*]], i64 2) ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %call = tail call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* %k, i64 2) + %call = tail call i32 @strncmp(ptr @key, ptr %k, i64 2) %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv } -define i32 @strncmp_memcmp_bad4([4 x i8]* dereferenceable (4) %buf) nofree nosync { +define i32 @strncmp_memcmp_bad4(ptr dereferenceable (4) %buf) nofree nosync { ; CHECK-LABEL: @strncmp_memcmp_bad4( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[CALL:%.*]] = call i32 @strncmp(i8* noundef nonnull [[STRING]], i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 2) +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strncmp(ptr noundef nonnull [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key, i64 2) ; CHECK-NEXT: tail call void @use(i32 [[CALL]]) ; CHECK-NEXT: ret i32 0 ; - %string = getelementptr inbounds [4 x i8], [4 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strncmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 2) + %call = call i32 @strncmp(ptr nonnull %buf, ptr @key, i64 2) tail call void @use(i32 %call) ret i32 0 } -define i32 @strcmp_memcmp_msan([12 x i8]* dereferenceable (12) %buf) sanitize_memory { +define i32 @strcmp_memcmp_msan(ptr dereferenceable (12) %buf) sanitize_memory { ; CHECK-LABEL: @strcmp_memcmp_msan( -; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(i8* noundef nonnull [[STRING]], i8* noundef nonnull dereferenceable(4) getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0)) +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr noundef nonnull [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key) ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] ; - %string = getelementptr inbounds [12 x i8], [12 x i8]* %buf, i64 0, i64 0 - %call = call i32 @strcmp(i8* nonnull %string, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0)) + %call = call i32 @strcmp(ptr nonnull %buf, ptr @key) %cmp = icmp eq i32 %call, 0 %conv = zext i1 %cmp to i32 ret i32 %conv } -declare i32 @memcmp(i8* nocapture, i8* nocapture, i64) +declare i32 @memcmp(ptr nocapture, ptr nocapture, i64) diff --git a/llvm/test/Transforms/InstCombine/strcpy-1.ll b/llvm/test/Transforms/InstCombine/strcpy-1.ll --- a/llvm/test/Transforms/InstCombine/strcpy-1.ll +++ b/llvm/test/Transforms/InstCombine/strcpy-1.ll @@ -11,78 +11,70 @@ @a = common global [32 x i8] zeroinitializer, align 1 @b = common global [32 x i8] zeroinitializer, align 1 -declare i8* @strcpy(i8*, i8*) +declare ptr @strcpy(ptr, ptr) define void @test_simplify1() { ; CHECK-LABEL: @test_simplify1( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(6) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0), i8* noundef nonnull align 1 dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 6, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr noundef nonnull align 1 dereferenceable(6) @a, ptr noundef nonnull align 1 dereferenceable(6) @hello, i32 6, i1 false) ; CHECK-NEXT: ret void ; - %dst = getelementptr [32 x i8], [32 x i8]* @a, i32 0, i32 0 - %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - call i8* @strcpy(i8* %dst, i8* %src) + call ptr @strcpy(ptr @a, ptr @hello) ret void } -define i8* @test_simplify2() { +define ptr @test_simplify2() { ; CHECK-LABEL: @test_simplify2( -; CHECK-NEXT: ret i8* getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0) +; CHECK-NEXT: ret ptr @a ; - %dst = getelementptr [32 x i8], [32 x i8]* @a, i32 0, i32 0 - %ret = call i8* @strcpy(i8* %dst, i8* %dst) - ret i8* %ret + %ret = call ptr @strcpy(ptr @a, ptr @a) + ret ptr %ret } -define void @test_simplify3(i8* %dst) { +define void @test_simplify3(ptr %dst) { ; CHECK-LABEL: @test_simplify3( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(80) [[DST:%.*]], i8* noundef nonnull align 1 dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 6, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr noundef nonnull align 1 dereferenceable(80) [[DST:%.*]], ptr noundef nonnull align 1 dereferenceable(6) @hello, i32 6, i1 false) ; CHECK-NEXT: ret void ; - %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - call i8* @strcpy(i8* dereferenceable(80) %dst, i8* %src) + call ptr @strcpy(ptr dereferenceable(80) %dst, ptr @hello) ret void } -define i8* @test_no_simplify1() { +define ptr @test_no_simplify1() { ; CHECK-LABEL: @test_no_simplify1( -; CHECK-NEXT: [[RET:%.*]] = call i8* @strcpy(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0), i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([32 x i8], [32 x i8]* @b, i32 0, i32 0)) -; CHECK-NEXT: ret i8* [[RET]] +; CHECK-NEXT: [[RET:%.*]] = call ptr @strcpy(ptr noundef nonnull @a, ptr noundef nonnull @b) +; CHECK-NEXT: ret ptr [[RET]] ; - %dst = getelementptr [32 x i8], [32 x i8]* @a, i32 0, i32 0 - %src = getelementptr [32 x i8], [32 x i8]* @b, i32 0, i32 0 - %ret = call i8* @strcpy(i8* %dst, i8* %src) - ret i8* %ret + %ret = call ptr @strcpy(ptr @a, ptr @b) + ret ptr %ret } -define i8* @test_no_simplify2(i8* %dst, i8* %src) { +define ptr @test_no_simplify2(ptr %dst, ptr %src) { ; CHECK-LABEL: @test_no_simplify2( -; CHECK-NEXT: %ret = musttail call i8* @strcpy(i8* %dst, i8* %src) -; CHECK-NEXT: ret i8* %ret +; CHECK-NEXT: [[RET:%.*]] = musttail call ptr @strcpy(ptr [[DST:%.*]], ptr [[SRC:%.*]]) +; CHECK-NEXT: ret ptr [[RET]] ; - %ret = musttail call i8* @strcpy(i8* %dst, i8* %src) - ret i8* %ret + %ret = musttail call ptr @strcpy(ptr %dst, ptr %src) + ret ptr %ret } define void @test_no_incompatible_attr() { ; CHECK-LABEL: @test_no_incompatible_attr( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(6) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0), i8* noundef nonnull align 1 dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 6, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr noundef nonnull align 1 dereferenceable(6) @a, ptr noundef nonnull align 1 dereferenceable(6) @hello, i32 6, i1 false) ; CHECK-NEXT: ret void ; - %dst = getelementptr [32 x i8], [32 x i8]* @a, i32 0, i32 0 - %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - call dereferenceable(1) i8* @strcpy(i8* %dst, i8* %src) + call dereferenceable(1) ptr @strcpy(ptr @a, ptr @hello) ret void } diff --git a/llvm/test/Transforms/InstCombine/strcpy_chk-1.ll b/llvm/test/Transforms/InstCombine/strcpy_chk-1.ll --- a/llvm/test/Transforms/InstCombine/strcpy_chk-1.ll +++ b/llvm/test/Transforms/InstCombine/strcpy_chk-1.ll @@ -12,147 +12,128 @@ ; Check cases where slen >= strlen (src). -define i8* @test_simplify1() { +define ptr @test_simplify1() { ; CHECK-LABEL: @test_simplify1( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* noundef nonnull align 1 dereferenceable(12) getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i1 false) -; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0) +; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr noundef nonnull align 1 dereferenceable(12) @a, ptr noundef nonnull align 1 dereferenceable(12) @.str, i32 12, i1 false) +; CHECK-NEXT: ret ptr @a ; - %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 - %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0, i32 0 - %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 60) - ret i8* %ret + %ret = call ptr @__strcpy_chk(ptr @a, ptr @.str, i32 60) + ret ptr %ret } -define i8* @test_simplify1_tail() { +define ptr @test_simplify1_tail() { ; CHECK-LABEL: @test_simplify1_tail( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* noundef nonnull align 1 dereferenceable(12) getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i1 false) -; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0) +; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i32(ptr noundef nonnull align 1 dereferenceable(12) @a, ptr noundef nonnull align 1 dereferenceable(12) @.str, i32 12, i1 false) +; CHECK-NEXT: ret ptr @a ; - %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 - %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0, i32 0 - %ret = tail call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 60) - ret i8* %ret + %ret = tail call ptr @__strcpy_chk(ptr @a, ptr @.str, i32 60) + ret ptr %ret } -define i8* @test_simplify2() { +define ptr @test_simplify2() { ; CHECK-LABEL: @test_simplify2( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* noundef nonnull align 1 dereferenceable(12) getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i1 false) -; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0) +; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr noundef nonnull align 1 dereferenceable(12) @a, ptr noundef nonnull align 1 dereferenceable(12) @.str, i32 12, i1 false) +; CHECK-NEXT: ret ptr @a ; - %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 - %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0, i32 0 - %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 12) - ret i8* %ret + %ret = call ptr @__strcpy_chk(ptr @a, ptr @.str, i32 12) + ret ptr %ret } -define i8* @test_simplify3() { +define ptr @test_simplify3() { ; CHECK-LABEL: @test_simplify3( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* noundef nonnull align 1 dereferenceable(12) getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i1 false) -; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0) +; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr noundef nonnull align 1 dereferenceable(12) @a, ptr noundef nonnull align 1 dereferenceable(12) @.str, i32 12, i1 false) +; CHECK-NEXT: ret ptr @a ; - %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 - %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0, i32 0 - %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 -1) - ret i8* %ret + %ret = call ptr @__strcpy_chk(ptr @a, ptr @.str, i32 -1) + ret ptr %ret } ; Check cases where there are no string constants. -define i8* @test_simplify4() { +define ptr @test_simplify4() { ; CHECK-LABEL: @test_simplify4( -; CHECK-NEXT: [[STRCPY:%.*]] = call i8* @strcpy(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @b, i32 0, i32 0)) -; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0) +; CHECK-NEXT: [[STRCPY:%.*]] = call ptr @strcpy(ptr noundef nonnull dereferenceable(1) @a, ptr noundef nonnull dereferenceable(1) @b) +; CHECK-NEXT: ret ptr @a ; - %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 - %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0 - %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 -1) - ret i8* %ret + %ret = call ptr @__strcpy_chk(ptr @a, ptr @b, i32 -1) + ret ptr %ret } -define i8* @test_simplify4_tail() { +define ptr @test_simplify4_tail() { ; CHECK-LABEL: @test_simplify4_tail( -; CHECK-NEXT: [[STRCPY:%.*]] = tail call i8* @strcpy(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @b, i32 0, i32 0)) -; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0) +; CHECK-NEXT: [[STRCPY:%.*]] = tail call ptr @strcpy(ptr noundef nonnull dereferenceable(1) @a, ptr noundef nonnull dereferenceable(1) @b) +; CHECK-NEXT: ret ptr @a ; - %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 - %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0 - %ret = tail call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 -1) - ret i8* %ret + %ret = tail call ptr @__strcpy_chk(ptr @a, ptr @b, i32 -1) + ret ptr %ret } ; Check case where the string length is not constant. -define i8* @test_simplify5() { +define ptr @test_simplify5() { ; CHECK-LABEL: @test_simplify5( -; CHECK-NEXT: [[LEN:%.*]] = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false, i1 false, i1 false) -; CHECK-NEXT: [[TMP1:%.*]] = call i8* @__memcpy_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i32 [[LEN]]) -; CHECK-NEXT: ret i8* [[TMP1]] +; CHECK-NEXT: [[LEN:%.*]] = call i32 @llvm.objectsize.i32.p0(ptr @a, i1 false, i1 false, i1 false) +; CHECK-NEXT: [[TMP1:%.*]] = call ptr @__memcpy_chk(ptr nonnull @a, ptr nonnull @.str, i32 12, i32 [[LEN]]) +; CHECK-NEXT: ret ptr [[TMP1]] ; - %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 - %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0, i32 0 - %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false, i1 false, i1 false) - %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 %len) - ret i8* %ret + %len = call i32 @llvm.objectsize.i32.p0(ptr @a, i1 false, i1 false, i1 false) + %ret = call ptr @__strcpy_chk(ptr @a, ptr @.str, i32 %len) + ret ptr %ret } ; Check case where the source and destination are the same. -define i8* @test_simplify6() { +define ptr @test_simplify6() { ; CHECK-LABEL: @test_simplify6( -; CHECK-NEXT: [[LEN:%.*]] = call i32 @llvm.objectsize.i32.p0i8(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i1 false, i1 false, i1 false) -; CHECK-NEXT: [[RET:%.*]] = call i8* @__strcpy_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i32 [[LEN]]) -; CHECK-NEXT: ret i8* [[RET]] +; CHECK-NEXT: [[LEN:%.*]] = call i32 @llvm.objectsize.i32.p0(ptr @a, i1 false, i1 false, i1 false) +; CHECK-NEXT: [[RET:%.*]] = call ptr @__strcpy_chk(ptr nonnull @a, ptr nonnull @a, i32 [[LEN]]) +; CHECK-NEXT: ret ptr [[RET]] ; - %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 - %len = call i32 @llvm.objectsize.i32.p0i8(i8* %dst, i1 false, i1 false, i1 false) - %ret = call i8* @__strcpy_chk(i8* %dst, i8* %dst, i32 %len) - ret i8* %ret + %len = call i32 @llvm.objectsize.i32.p0(ptr @a, i1 false, i1 false, i1 false) + %ret = call ptr @__strcpy_chk(ptr @a, ptr @a, i32 %len) + ret ptr %ret } ; Check cases where there are no string constants, and is a tail call. -define i8* @test_simplify7() { +define ptr @test_simplify7() { ; CHECK-LABEL: @test_simplify7( -; CHECK-NEXT: [[STRCPY:%.*]] = tail call i8* @strcpy(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @b, i32 0, i32 0)) -; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0) +; CHECK-NEXT: [[STRCPY:%.*]] = tail call ptr @strcpy(ptr noundef nonnull dereferenceable(1) @a, ptr noundef nonnull dereferenceable(1) @b) +; CHECK-NEXT: ret ptr @a ; - %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 - %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0 - %ret = tail call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 -1) - ret i8* %ret + %ret = tail call ptr @__strcpy_chk(ptr @a, ptr @b, i32 -1) + ret ptr %ret } ; Check case where slen < strlen (src). -define i8* @test_no_simplify1() { +define ptr @test_no_simplify1() { ; CHECK-LABEL: @test_no_simplify1( -; CHECK-NEXT: [[RET:%.*]] = call i8* @__strcpy_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i32 0, i32 0), i32 8) -; CHECK-NEXT: ret i8* [[RET]] +; CHECK-NEXT: [[RET:%.*]] = call ptr @__strcpy_chk(ptr nonnull @a, ptr nonnull @b, i32 8) +; CHECK-NEXT: ret ptr [[RET]] ; - %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 - %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0 - %ret = call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 8) - ret i8* %ret + %ret = call ptr @__strcpy_chk(ptr @a, ptr @b, i32 8) + ret ptr %ret } -define i8* @test_no_simplify2(i8* %dst, i8* %src, i32 %a) { +define ptr @test_no_simplify2(ptr %dst, ptr %src, i32 %a) { ; CHECK-LABEL: @test_no_simplify2( -; CHECK-NEXT: %ret = musttail call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 60) -; CHECK-NEXT: ret i8* %ret +; CHECK-NEXT: [[RET:%.*]] = musttail call ptr @__strcpy_chk(ptr [[DST:%.*]], ptr [[SRC:%.*]], i32 60) +; CHECK-NEXT: ret ptr [[RET]] ; - %ret = musttail call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 60) - ret i8* %ret + %ret = musttail call ptr @__strcpy_chk(ptr %dst, ptr %src, i32 60) + ret ptr %ret } -declare i8* @__strcpy_chk(i8*, i8*, i32) nounwind -declare i32 @llvm.objectsize.i32.p0i8(i8*, i1, i1, i1) nounwind readonly +declare ptr @__strcpy_chk(ptr, ptr, i32) nounwind +declare i32 @llvm.objectsize.i32.p0(ptr, i1, i1, i1) nounwind readonly diff --git a/llvm/test/Transforms/InstCombine/strcpy_chk-64.ll b/llvm/test/Transforms/InstCombine/strcpy_chk-64.ll --- a/llvm/test/Transforms/InstCombine/strcpy_chk-64.ll +++ b/llvm/test/Transforms/InstCombine/strcpy_chk-64.ll @@ -3,42 +3,38 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" target triple = "x86_64-apple-darwin10.0.0" -define void @func(i8* %i) nounwind ssp { +define void @func(ptr %i) nounwind ssp { ; CHECK-LABEL: @func( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[S:%.*]] = alloca [32 x i8], align 16 -; CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* [[S]], i64 0, i64 0 -; CHECK-NEXT: [[CALL:%.*]] = call i8* @__strcpy_chk(i8* nonnull [[ARRAYDECAY]], i8* [[I:%.*]], i64 32) -; CHECK-NEXT: call void @func2(i8* nonnull [[ARRAYDECAY]]) [[ATTR2:#.*]] +; CHECK-NEXT: [[CALL:%.*]] = call ptr @__strcpy_chk(ptr nonnull [[S]], ptr [[I:%.*]], i64 32) +; CHECK-NEXT: call void @func2(ptr nonnull [[S]]) #[[ATTR2:[0-9]+]] ; CHECK-NEXT: ret void ; entry: %s = alloca [32 x i8], align 16 - %arraydecay = getelementptr inbounds [32 x i8], [32 x i8]* %s, i32 0, i32 0 - %call = call i8* @__strcpy_chk(i8* %arraydecay, i8* %i, i64 32) - call void @func2(i8* %arraydecay) + %call = call ptr @__strcpy_chk(ptr %s, ptr %i, i64 32) + call void @func2(ptr %s) ret void } -define void @func_no_null_opt(i8* %i) nounwind ssp #0 { +define void @func_no_null_opt(ptr %i) nounwind ssp #0 { ; CHECK-LABEL: @func_no_null_opt( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[S:%.*]] = alloca [32 x i8], align 16 -; CHECK-NEXT: [[ARRAYDECAY:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* [[S]], i64 0, i64 0 -; CHECK-NEXT: [[CALL:%.*]] = call i8* @__strcpy_chk(i8* [[ARRAYDECAY]], i8* [[I:%.*]], i64 32) -; CHECK-NEXT: call void @func2(i8* [[ARRAYDECAY]]) [[ATTR2]] +; CHECK-NEXT: [[CALL:%.*]] = call ptr @__strcpy_chk(ptr nonnull [[S]], ptr [[I:%.*]], i64 32) +; CHECK-NEXT: call void @func2(ptr nonnull [[S]]) #[[ATTR2]] ; CHECK-NEXT: ret void ; entry: %s = alloca [32 x i8], align 16 - %arraydecay = getelementptr inbounds [32 x i8], [32 x i8]* %s, i32 0, i32 0 - %call = call i8* @__strcpy_chk(i8* %arraydecay, i8* %i, i64 32) - call void @func2(i8* %arraydecay) + %call = call ptr @__strcpy_chk(ptr %s, ptr %i, i64 32) + call void @func2(ptr %s) ret void } -declare i8* @__strcpy_chk(i8*, i8*, i64) nounwind +declare ptr @__strcpy_chk(ptr, ptr, i64) nounwind -declare void @func2(i8*) +declare void @func2(ptr) attributes #0 = { null_pointer_is_valid } diff --git a/llvm/test/Transforms/InstCombine/strlcpy-1.ll b/llvm/test/Transforms/InstCombine/strlcpy-1.ll --- a/llvm/test/Transforms/InstCombine/strlcpy-1.ll +++ b/llvm/test/Transforms/InstCombine/strlcpy-1.ll @@ -6,9 +6,9 @@ ; ; Test that the strncpy library call simplifier works correctly. -declare i64 @strlcpy(i8*, i8*, i64) +declare i64 @strlcpy(ptr, ptr, i64) -declare void @sink(i8*, i64) +declare void @sink(ptr, i64) @s4 = constant [5 x i8] c"1234\00" @@ -17,28 +17,28 @@ ; Verify that strlcpy(D, "", N) calls are transformed to a nul store ; to *D for nonzero N and folded to zero for all values of N. -define void @fold_strlcpy_s0(i8* %dst) { +define void @fold_strlcpy_s0(ptr %dst) { ; ANY-LABEL: @fold_strlcpy_s0( -; ANY-NEXT: call void @sink(i8* [[DST:%.*]], i64 0) -; ANY-NEXT: store i8 0, i8* [[DST]], align 1 -; ANY-NEXT: call void @sink(i8* nonnull [[DST]], i64 0) -; ANY-NEXT: store i8 0, i8* [[DST]], align 1 -; ANY-NEXT: call void @sink(i8* nonnull [[DST]], i64 0) +; ANY-NEXT: call void @sink(ptr [[DST:%.*]], i64 0) +; ANY-NEXT: store i8 0, ptr [[DST]], align 1 +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], i64 0) +; ANY-NEXT: store i8 0, ptr [[DST]], align 1 +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], i64 0) ; ANY-NEXT: ret void ; - %ps0 = getelementptr [5 x i8], [5 x i8]* @s4, i32 0, i32 4 + %ps0 = getelementptr [5 x i8], ptr @s4, i32 0, i32 4 ; Fold strlcpy(D, "", 0) to just 0. - %ns0_0 = call i64 @strlcpy(i8* %dst, i8* %ps0, i64 0) - call void @sink(i8* %dst, i64 %ns0_0) + %ns0_0 = call i64 @strlcpy(ptr %dst, ptr %ps0, i64 0) + call void @sink(ptr %dst, i64 %ns0_0) ; Transform strlcpy(D, "", 1) to *D = '\0, 0. - %ns0_1 = call i64 @strlcpy(i8* %dst, i8* %ps0, i64 1) - call void @sink(i8* %dst, i64 %ns0_1) + %ns0_1 = call i64 @strlcpy(ptr %dst, ptr %ps0, i64 1) + call void @sink(ptr %dst, i64 %ns0_1) ; Transform strlcpy(D, "", SIZE_MAX) to *D = '\0, 0. - %ns0_m1 = call i64 @strlcpy(i8* %dst, i8* %ps0, i64 -1) - call void @sink(i8* %dst, i64 %ns0_m1) + %ns0_m1 = call i64 @strlcpy(ptr %dst, ptr %ps0, i64 -1) + call void @sink(ptr %dst, i64 %ns0_m1) ret void } @@ -48,58 +48,52 @@ ; D[0] for nonzero N (and a nul store to D[1] for N greater than 1) ; and folded to 1 for all values of N. -define void @fold_strlcpy_s1(i8* %dst) { +define void @fold_strlcpy_s1(ptr %dst) { ; BE-LABEL: @fold_strlcpy_s1( -; BE-NEXT: call void @sink(i8* [[DST:%.*]], i64 1) -; BE-NEXT: store i8 0, i8* [[DST]], align 1 -; BE-NEXT: call void @sink(i8* nonnull [[DST]], i64 1) -; BE-NEXT: [[TMP1:%.*]] = bitcast i8* [[DST]] to i16* -; BE-NEXT: store i16 13312, i16* [[TMP1]], align 1 -; BE-NEXT: call void @sink(i8* nonnull [[DST]], i64 1) -; BE-NEXT: [[TMP2:%.*]] = bitcast i8* [[DST]] to i16* -; BE-NEXT: store i16 13312, i16* [[TMP2]], align 1 -; BE-NEXT: call void @sink(i8* nonnull [[DST]], i64 1) -; BE-NEXT: [[TMP3:%.*]] = bitcast i8* [[DST]] to i16* -; BE-NEXT: store i16 13312, i16* [[TMP3]], align 1 -; BE-NEXT: call void @sink(i8* nonnull [[DST]], i64 1) +; BE-NEXT: call void @sink(ptr [[DST:%.*]], i64 1) +; BE-NEXT: store i8 0, ptr [[DST]], align 1 +; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 1) +; BE-NEXT: store i16 13312, ptr [[DST]], align 1 +; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 1) +; BE-NEXT: store i16 13312, ptr [[DST]], align 1 +; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 1) +; BE-NEXT: store i16 13312, ptr [[DST]], align 1 +; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 1) ; BE-NEXT: ret void ; ; LE-LABEL: @fold_strlcpy_s1( -; LE-NEXT: call void @sink(i8* [[DST:%.*]], i64 1) -; LE-NEXT: store i8 0, i8* [[DST]], align 1 -; LE-NEXT: call void @sink(i8* nonnull [[DST]], i64 1) -; LE-NEXT: [[TMP1:%.*]] = bitcast i8* [[DST]] to i16* -; LE-NEXT: store i16 52, i16* [[TMP1]], align 1 -; LE-NEXT: call void @sink(i8* nonnull [[DST]], i64 1) -; LE-NEXT: [[TMP2:%.*]] = bitcast i8* [[DST]] to i16* -; LE-NEXT: store i16 52, i16* [[TMP2]], align 1 -; LE-NEXT: call void @sink(i8* nonnull [[DST]], i64 1) -; LE-NEXT: [[TMP3:%.*]] = bitcast i8* [[DST]] to i16* -; LE-NEXT: store i16 52, i16* [[TMP3]], align 1 -; LE-NEXT: call void @sink(i8* nonnull [[DST]], i64 1) +; LE-NEXT: call void @sink(ptr [[DST:%.*]], i64 1) +; LE-NEXT: store i8 0, ptr [[DST]], align 1 +; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 1) +; LE-NEXT: store i16 52, ptr [[DST]], align 1 +; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 1) +; LE-NEXT: store i16 52, ptr [[DST]], align 1 +; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 1) +; LE-NEXT: store i16 52, ptr [[DST]], align 1 +; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 1) ; LE-NEXT: ret void ; - %ps1 = getelementptr [5 x i8], [5 x i8]* @s4, i32 0, i32 3 + %ps1 = getelementptr [5 x i8], ptr @s4, i32 0, i32 3 ; Fold strlcpy(D, "4", 0) to 1. - %ns1_0 = call i64 @strlcpy(i8* %dst, i8* %ps1, i64 0) - call void @sink(i8* %dst, i64 %ns1_0) + %ns1_0 = call i64 @strlcpy(ptr %dst, ptr %ps1, i64 0) + call void @sink(ptr %dst, i64 %ns1_0) ; Transform strlcpy(D, "4", 1) to *D = '\0', 1. - %ns1_1 = call i64 @strlcpy(i8* %dst, i8* %ps1, i64 1) - call void @sink(i8* %dst, i64 %ns1_1) + %ns1_1 = call i64 @strlcpy(ptr %dst, ptr %ps1, i64 1) + call void @sink(ptr %dst, i64 %ns1_1) ; Transform strlcpy(D, "4", 2) to D[0] = '\4, D[1] = '\0', 1. - %ns1_2 = call i64 @strlcpy(i8* %dst, i8* %ps1, i64 2) - call void @sink(i8* %dst, i64 %ns1_2) + %ns1_2 = call i64 @strlcpy(ptr %dst, ptr %ps1, i64 2) + call void @sink(ptr %dst, i64 %ns1_2) ; Transform strlcpy(D, "4", 3) to D[0] = '\4, D[1] = '\0', 1.. - %ns1_3 = call i64 @strlcpy(i8* %dst, i8* %ps1, i64 3) - call void @sink(i8* %dst, i64 %ns1_3) + %ns1_3 = call i64 @strlcpy(ptr %dst, ptr %ps1, i64 3) + call void @sink(ptr %dst, i64 %ns1_3) ; Transform strlcpy(D, "4", SIZE_MAX) to D[0] = '\4, D[1] = '\0', 1. - %ns1_m1 = call i64 @strlcpy(i8* %dst, i8* %ps1, i64 -1) - call void @sink(i8* %dst, i64 %ns1_m1) + %ns1_m1 = call i64 @strlcpy(ptr %dst, ptr %ps1, i64 -1) + call void @sink(ptr %dst, i64 %ns1_m1) ret void } @@ -109,90 +103,87 @@ ; the N - 1 leading characters of the string to D and folded to 4 for ; all values of N. -define void @fold_strlcpy_s5(i8* %dst) { +define void @fold_strlcpy_s5(ptr %dst) { ; BE-LABEL: @fold_strlcpy_s5( -; BE-NEXT: call void @sink(i8* [[DST:%.*]], i64 4) -; BE-NEXT: store i8 0, i8* [[DST]], align 1 -; BE-NEXT: call void @sink(i8* nonnull [[DST]], i64 4) -; BE-NEXT: store i8 49, i8* [[DST]], align 1 -; BE-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, i8* [[DST]], i64 1 -; BE-NEXT: store i8 0, i8* [[TMP1]], align 1 -; BE-NEXT: call void @sink(i8* nonnull [[DST]], i64 4) -; BE-NEXT: [[TMP2:%.*]] = bitcast i8* [[DST]] to i16* -; BE-NEXT: store i16 12594, i16* [[TMP2]], align 1 -; BE-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, i8* [[DST]], i64 2 -; BE-NEXT: store i8 0, i8* [[TMP3]], align 1 -; BE-NEXT: call void @sink(i8* nonnull [[DST]], i64 4) -; BE-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(3) [[DST]], i8* noundef nonnull align 1 dereferenceable(3) getelementptr inbounds ([5 x i8], [5 x i8]* @s4, i64 0, i64 0), i64 3, i1 false) -; BE-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, i8* [[DST]], i64 3 -; BE-NEXT: store i8 0, i8* [[TMP4]], align 1 -; BE-NEXT: call void @sink(i8* nonnull [[DST]], i64 4) -; BE-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(5) [[DST]], i8* noundef nonnull align 1 dereferenceable(5) getelementptr inbounds ([5 x i8], [5 x i8]* @s4, i64 0, i64 0), i64 5, i1 false) -; BE-NEXT: call void @sink(i8* nonnull [[DST]], i64 4) -; BE-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(5) [[DST]], i8* noundef nonnull align 1 dereferenceable(5) getelementptr inbounds ([5 x i8], [5 x i8]* @s4, i64 0, i64 0), i64 5, i1 false) -; BE-NEXT: call void @sink(i8* nonnull [[DST]], i64 4) -; BE-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(5) [[DST]], i8* noundef nonnull align 1 dereferenceable(5) getelementptr inbounds ([5 x i8], [5 x i8]* @s4, i64 0, i64 0), i64 5, i1 false) -; BE-NEXT: call void @sink(i8* nonnull [[DST]], i64 4) +; BE-NEXT: call void @sink(ptr [[DST:%.*]], i64 4) +; BE-NEXT: store i8 0, ptr [[DST]], align 1 +; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) +; BE-NEXT: store i8 49, ptr [[DST]], align 1 +; BE-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1 +; BE-NEXT: store i8 0, ptr [[TMP1]], align 1 +; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) +; BE-NEXT: store i16 12594, ptr [[DST]], align 1 +; BE-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 2 +; BE-NEXT: store i8 0, ptr [[TMP2]], align 1 +; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) +; BE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(3) [[DST]], ptr noundef nonnull align 1 dereferenceable(3) @s4, i64 3, i1 false) +; BE-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 3 +; BE-NEXT: store i8 0, ptr [[TMP3]], align 1 +; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) +; BE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @s4, i64 5, i1 false) +; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) +; BE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @s4, i64 5, i1 false) +; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) +; BE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @s4, i64 5, i1 false) +; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) ; BE-NEXT: ret void ; ; LE-LABEL: @fold_strlcpy_s5( -; LE-NEXT: call void @sink(i8* [[DST:%.*]], i64 4) -; LE-NEXT: store i8 0, i8* [[DST]], align 1 -; LE-NEXT: call void @sink(i8* nonnull [[DST]], i64 4) -; LE-NEXT: store i8 49, i8* [[DST]], align 1 -; LE-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, i8* [[DST]], i64 1 -; LE-NEXT: store i8 0, i8* [[TMP1]], align 1 -; LE-NEXT: call void @sink(i8* nonnull [[DST]], i64 4) -; LE-NEXT: [[TMP2:%.*]] = bitcast i8* [[DST]] to i16* -; LE-NEXT: store i16 12849, i16* [[TMP2]], align 1 -; LE-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, i8* [[DST]], i64 2 -; LE-NEXT: store i8 0, i8* [[TMP3]], align 1 -; LE-NEXT: call void @sink(i8* nonnull [[DST]], i64 4) -; LE-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(3) [[DST]], i8* noundef nonnull align 1 dereferenceable(3) getelementptr inbounds ([5 x i8], [5 x i8]* @s4, i64 0, i64 0), i64 3, i1 false) -; LE-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, i8* [[DST]], i64 3 -; LE-NEXT: store i8 0, i8* [[TMP4]], align 1 -; LE-NEXT: call void @sink(i8* nonnull [[DST]], i64 4) -; LE-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(5) [[DST]], i8* noundef nonnull align 1 dereferenceable(5) getelementptr inbounds ([5 x i8], [5 x i8]* @s4, i64 0, i64 0), i64 5, i1 false) -; LE-NEXT: call void @sink(i8* nonnull [[DST]], i64 4) -; LE-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(5) [[DST]], i8* noundef nonnull align 1 dereferenceable(5) getelementptr inbounds ([5 x i8], [5 x i8]* @s4, i64 0, i64 0), i64 5, i1 false) -; LE-NEXT: call void @sink(i8* nonnull [[DST]], i64 4) -; LE-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(5) [[DST]], i8* noundef nonnull align 1 dereferenceable(5) getelementptr inbounds ([5 x i8], [5 x i8]* @s4, i64 0, i64 0), i64 5, i1 false) -; LE-NEXT: call void @sink(i8* nonnull [[DST]], i64 4) +; LE-NEXT: call void @sink(ptr [[DST:%.*]], i64 4) +; LE-NEXT: store i8 0, ptr [[DST]], align 1 +; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) +; LE-NEXT: store i8 49, ptr [[DST]], align 1 +; LE-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1 +; LE-NEXT: store i8 0, ptr [[TMP1]], align 1 +; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) +; LE-NEXT: store i16 12849, ptr [[DST]], align 1 +; LE-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 2 +; LE-NEXT: store i8 0, ptr [[TMP2]], align 1 +; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) +; LE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(3) [[DST]], ptr noundef nonnull align 1 dereferenceable(3) @s4, i64 3, i1 false) +; LE-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 3 +; LE-NEXT: store i8 0, ptr [[TMP3]], align 1 +; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) +; LE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @s4, i64 5, i1 false) +; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) +; LE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @s4, i64 5, i1 false) +; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) +; LE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @s4, i64 5, i1 false) +; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) ; LE-NEXT: ret void ; - %ps4 = getelementptr [5 x i8], [5 x i8]* @s4, i32 0, i32 0 ; Fold strlcpy(D, "1234", 0) to 4. - %ns4_0 = call i64 @strlcpy(i8* %dst, i8* %ps4, i64 0) - call void @sink(i8* %dst, i64 %ns4_0) + %ns4_0 = call i64 @strlcpy(ptr %dst, ptr @s4, i64 0) + call void @sink(ptr %dst, i64 %ns4_0) ; Transform strlcpy(D, "1234", 1) to *D = '\0', 4. - %ns4_1 = call i64 @strlcpy(i8* %dst, i8* %ps4, i64 1) - call void @sink(i8* %dst, i64 %ns4_1) + %ns4_1 = call i64 @strlcpy(ptr %dst, ptr @s4, i64 1) + call void @sink(ptr %dst, i64 %ns4_1) ; Transform strlcpy(D, "1234", 2) to D[0] = '1', D[1] = '\0', 4. - %ns4_2 = call i64 @strlcpy(i8* %dst, i8* %ps4, i64 2) - call void @sink(i8* %dst, i64 %ns4_2) + %ns4_2 = call i64 @strlcpy(ptr %dst, ptr @s4, i64 2) + call void @sink(ptr %dst, i64 %ns4_2) ; Transform strlcpy(D, S="1234", 3) to memcpy(D, S, 2), D[2] = '\0', 4. - %ns4_3 = call i64 @strlcpy(i8* %dst, i8* %ps4, i64 3) - call void @sink(i8* %dst, i64 %ns4_3) + %ns4_3 = call i64 @strlcpy(ptr %dst, ptr @s4, i64 3) + call void @sink(ptr %dst, i64 %ns4_3) ; Transform strlcpy(D, S="1234", 4) to memcpy(D, S, 3), D[3] = '\0', 4. - %ns4_4 = call i64 @strlcpy(i8* %dst, i8* %ps4, i64 4) - call void @sink(i8* %dst, i64 %ns4_4) + %ns4_4 = call i64 @strlcpy(ptr %dst, ptr @s4, i64 4) + call void @sink(ptr %dst, i64 %ns4_4) ; Transform strlcpy(D, S="1234", 5) to memcpy(D, S, 5), 4. - %ns4_5 = call i64 @strlcpy(i8* %dst, i8* %ps4, i64 5) - call void @sink(i8* %dst, i64 %ns4_5) + %ns4_5 = call i64 @strlcpy(ptr %dst, ptr @s4, i64 5) + call void @sink(ptr %dst, i64 %ns4_5) ; Transform strlcpy(D, S="1234", 9) to memcpy(D, S, 5), 4. - %ns4_9 = call i64 @strlcpy(i8* %dst, i8* %ps4, i64 5) - call void @sink(i8* %dst, i64 %ns4_9) + %ns4_9 = call i64 @strlcpy(ptr %dst, ptr @s4, i64 5) + call void @sink(ptr %dst, i64 %ns4_9) ; Transform strlcpy(D, S="1234", SIZE_MAX) to memcpy(D, S, 5), 4. - %ns4_m1 = call i64 @strlcpy(i8* %dst, i8* %ps4, i64 -1) - call void @sink(i8* %dst, i64 %ns4_m1) + %ns4_m1 = call i64 @strlcpy(ptr %dst, ptr @s4, i64 -1) + call void @sink(ptr %dst, i64 %ns4_m1) ret void } @@ -201,30 +192,30 @@ ; to *D, strlcpy(D, S, 0) to a no-op, and the result of both folded ; to strlen(S). -define void @fold_strlcpy_s_0(i8* %dst, i8* %s, i64 %n) { +define void @fold_strlcpy_s_0(ptr %dst, ptr %s, i64 %n) { ; ANY-LABEL: @fold_strlcpy_s_0( -; ANY-NEXT: store i8 0, i8* [[DST:%.*]], align 1 -; ANY-NEXT: [[STRLEN:%.*]] = call i64 @strlen(i8* noundef nonnull dereferenceable(1) [[S:%.*]]) -; ANY-NEXT: call void @sink(i8* nonnull [[DST]], i64 [[STRLEN]]) -; ANY-NEXT: [[STRLEN1:%.*]] = call i64 @strlen(i8* noundef nonnull dereferenceable(1) [[S]]) -; ANY-NEXT: call void @sink(i8* nonnull [[DST]], i64 [[STRLEN1]]) -; ANY-NEXT: [[STRLEN2:%.*]] = call i64 @strlen(i8* noundef nonnull dereferenceable(1) [[S]]) -; ANY-NEXT: call void @sink(i8* nonnull [[DST]], i64 [[STRLEN2]]) +; ANY-NEXT: store i8 0, ptr [[DST:%.*]], align 1 +; ANY-NEXT: [[STRLEN:%.*]] = call i64 @strlen(ptr noundef nonnull dereferenceable(1) [[S:%.*]]) +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], i64 [[STRLEN]]) +; ANY-NEXT: [[STRLEN1:%.*]] = call i64 @strlen(ptr noundef nonnull dereferenceable(1) [[S]]) +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], i64 [[STRLEN1]]) +; ANY-NEXT: [[STRLEN2:%.*]] = call i64 @strlen(ptr noundef nonnull dereferenceable(1) [[S]]) +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], i64 [[STRLEN2]]) ; ANY-NEXT: ret void ; ; Transform strlcpy(D, S, 1) to *D = '\0', strlen(S). - %ns_1 = call i64 @strlcpy(i8* %dst, i8* %s, i64 1) - call void @sink(i8* %dst, i64 %ns_1) + %ns_1 = call i64 @strlcpy(ptr %dst, ptr %s, i64 1) + call void @sink(ptr %dst, i64 %ns_1) ; For strlcpy(D, S, 0) to strlen(S). - %ns_0 = call i64 @strlcpy(i8* %dst, i8* %s, i64 0) - call void @sink(i8* %dst, i64 %ns_0) + %ns_0 = call i64 @strlcpy(ptr %dst, ptr %s, i64 0) + call void @sink(ptr %dst, i64 %ns_0) ; Verify that calling strlcpy with a null destination is also folded ; (to match a possible extension of some implementations that emulate ; snprintf(0, 0, "%s", S)). - %n0_s_0 = call i64 @strlcpy(i8* null, i8* %s, i64 0) - call void @sink(i8* %dst, i64 %n0_s_0) + %n0_s_0 = call i64 @strlcpy(ptr null, ptr %s, i64 0) + call void @sink(ptr %dst, i64 %n0_s_0) ret void } @@ -235,45 +226,44 @@ ; annotate the destination argument with the dereferenceable attribute ; only with nonzero N. -define void @call_strlcpy_s0_n(i8* %dst, i8* %s, i64 %n) { +define void @call_strlcpy_s0_n(ptr %dst, ptr %s, i64 %n) { ; ANY-LABEL: @call_strlcpy_s0_n( -; ANY-NEXT: [[NS_2:%.*]] = call i64 @strlcpy(i8* noundef nonnull dereferenceable(1) [[DST:%.*]], i8* noundef nonnull dereferenceable(1) [[S:%.*]], i64 2) -; ANY-NEXT: call void @sink(i8* [[DST]], i64 [[NS_2]]) -; ANY-NEXT: [[NS_N:%.*]] = call i64 @strlcpy(i8* [[DST]], i8* noundef nonnull dereferenceable(1) [[S]], i64 [[N:%.*]]) -; ANY-NEXT: call void @sink(i8* [[DST]], i64 [[NS_N]]) +; ANY-NEXT: [[NS_2:%.*]] = call i64 @strlcpy(ptr noundef nonnull dereferenceable(1) [[DST:%.*]], ptr noundef nonnull dereferenceable(1) [[S:%.*]], i64 2) +; ANY-NEXT: call void @sink(ptr [[DST]], i64 [[NS_2]]) +; ANY-NEXT: [[NS_N:%.*]] = call i64 @strlcpy(ptr [[DST]], ptr noundef nonnull dereferenceable(1) [[S]], i64 [[N:%.*]]) +; ANY-NEXT: call void @sink(ptr [[DST]], i64 [[NS_N]]) ; ANY-NEXT: [[NZ:%.*]] = or i64 [[N]], 1 -; ANY-NEXT: [[NS_NZ:%.*]] = call i64 @strlcpy(i8* noundef nonnull dereferenceable(1) [[DST]], i8* noundef nonnull dereferenceable(1) [[S]], i64 [[NZ]]) -; ANY-NEXT: call void @sink(i8* [[DST]], i64 [[NS_NZ]]) -; ANY-NEXT: [[NS0_N:%.*]] = call i64 @strlcpy(i8* [[DST]], i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x i8], [5 x i8]* @s4, i64 0, i64 4), i64 [[N]]) -; ANY-NEXT: call void @sink(i8* [[DST]], i64 [[NS0_N]]) -; ANY-NEXT: [[NS1_N:%.*]] = call i64 @strlcpy(i8* [[DST]], i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x i8], [5 x i8]* @s4, i64 0, i64 3), i64 [[N]]) -; ANY-NEXT: call void @sink(i8* [[DST]], i64 [[NS1_N]]) -; ANY-NEXT: [[NS4_N:%.*]] = call i64 @strlcpy(i8* [[DST]], i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x i8], [5 x i8]* @s4, i64 0, i64 0), i64 [[N]]) -; ANY-NEXT: call void @sink(i8* [[DST]], i64 [[NS4_N]]) +; ANY-NEXT: [[NS_NZ:%.*]] = call i64 @strlcpy(ptr noundef nonnull dereferenceable(1) [[DST]], ptr noundef nonnull dereferenceable(1) [[S]], i64 [[NZ]]) +; ANY-NEXT: call void @sink(ptr [[DST]], i64 [[NS_NZ]]) +; ANY-NEXT: [[NS0_N:%.*]] = call i64 @strlcpy(ptr [[DST]], ptr noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x i8], ptr @s4, i64 0, i64 4), i64 [[N]]) +; ANY-NEXT: call void @sink(ptr [[DST]], i64 [[NS0_N]]) +; ANY-NEXT: [[NS1_N:%.*]] = call i64 @strlcpy(ptr [[DST]], ptr noundef nonnull dereferenceable(1) getelementptr inbounds ([5 x i8], ptr @s4, i64 0, i64 3), i64 [[N]]) +; ANY-NEXT: call void @sink(ptr [[DST]], i64 [[NS1_N]]) +; ANY-NEXT: [[NS4_N:%.*]] = call i64 @strlcpy(ptr [[DST]], ptr noundef nonnull @s4, i64 [[N]]) +; ANY-NEXT: call void @sink(ptr [[DST]], i64 [[NS4_N]]) ; ANY-NEXT: ret void ; - %ns_2 = call i64 @strlcpy(i8* %dst, i8* %s, i64 2) - call void @sink(i8* %dst, i64 %ns_2) + %ns_2 = call i64 @strlcpy(ptr %dst, ptr %s, i64 2) + call void @sink(ptr %dst, i64 %ns_2) - %ns_n = call i64 @strlcpy(i8* %dst, i8* %s, i64 %n) - call void @sink(i8* %dst, i64 %ns_n) + %ns_n = call i64 @strlcpy(ptr %dst, ptr %s, i64 %n) + call void @sink(ptr %dst, i64 %ns_n) %nz = or i64 %n, 1 - %ns_nz = call i64 @strlcpy(i8* %dst, i8* %s, i64 %nz) - call void @sink(i8* %dst, i64 %ns_nz) + %ns_nz = call i64 @strlcpy(ptr %dst, ptr %s, i64 %nz) + call void @sink(ptr %dst, i64 %ns_nz) - %ps0 = getelementptr [5 x i8], [5 x i8]* @s4, i32 0, i32 4 - %ns0_n = call i64 @strlcpy(i8* %dst, i8* %ps0, i64 %n) - call void @sink(i8* %dst, i64 %ns0_n) + %ps0 = getelementptr [5 x i8], ptr @s4, i32 0, i32 4 + %ns0_n = call i64 @strlcpy(ptr %dst, ptr %ps0, i64 %n) + call void @sink(ptr %dst, i64 %ns0_n) - %ps1 = getelementptr [5 x i8], [5 x i8]* @s4, i32 0, i32 3 - %ns1_n = call i64 @strlcpy(i8* %dst, i8* %ps1, i64 %n) - call void @sink(i8* %dst, i64 %ns1_n) + %ps1 = getelementptr [5 x i8], ptr @s4, i32 0, i32 3 + %ns1_n = call i64 @strlcpy(ptr %dst, ptr %ps1, i64 %n) + call void @sink(ptr %dst, i64 %ns1_n) - %ps4 = getelementptr [5 x i8], [5 x i8]* @s4, i32 0, i32 0 - %ns4_n = call i64 @strlcpy(i8* %dst, i8* %ps4, i64 %n) - call void @sink(i8* %dst, i64 %ns4_n) + %ns4_n = call i64 @strlcpy(ptr %dst, ptr @s4, i64 %n) + call void @sink(ptr %dst, i64 %ns4_n) ret void } @@ -287,71 +277,68 @@ ; undefined so technically reading past the end would be fine but it's ; easy to avoid. -define void @fold_strlcpy_a5(i8* %dst, i64 %n) { +define void @fold_strlcpy_a5(ptr %dst, i64 %n) { ; BE-LABEL: @fold_strlcpy_a5( -; BE-NEXT: call void @sink(i8* [[DST:%.*]], i64 5) -; BE-NEXT: store i8 0, i8* [[DST]], align 1 -; BE-NEXT: call void @sink(i8* nonnull [[DST]], i64 5) -; BE-NEXT: store i8 49, i8* [[DST]], align 1 -; BE-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, i8* [[DST]], i64 1 -; BE-NEXT: store i8 0, i8* [[TMP1]], align 1 -; BE-NEXT: call void @sink(i8* nonnull [[DST]], i64 5) -; BE-NEXT: [[TMP2:%.*]] = bitcast i8* [[DST]] to i32* -; BE-NEXT: store i32 825373492, i32* [[TMP2]], align 1 -; BE-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, i8* [[DST]], i64 4 -; BE-NEXT: store i8 0, i8* [[TMP3]], align 1 -; BE-NEXT: call void @sink(i8* nonnull [[DST]], i64 5) -; BE-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(5) [[DST]], i8* noundef nonnull align 1 dereferenceable(5) getelementptr inbounds ([5 x i8], [5 x i8]* @a5, i64 0, i64 0), i64 5, i1 false) -; BE-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, i8* [[DST]], i64 5 -; BE-NEXT: store i8 0, i8* [[TMP4]], align 1 -; BE-NEXT: call void @sink(i8* nonnull [[DST]], i64 5) -; BE-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(5) [[DST]], i8* noundef nonnull align 1 dereferenceable(5) getelementptr inbounds ([5 x i8], [5 x i8]* @a5, i64 0, i64 0), i64 5, i1 false) -; BE-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, i8* [[DST]], i64 5 -; BE-NEXT: store i8 0, i8* [[TMP5]], align 1 -; BE-NEXT: call void @sink(i8* nonnull [[DST]], i64 5) +; BE-NEXT: call void @sink(ptr [[DST:%.*]], i64 5) +; BE-NEXT: store i8 0, ptr [[DST]], align 1 +; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 5) +; BE-NEXT: store i8 49, ptr [[DST]], align 1 +; BE-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1 +; BE-NEXT: store i8 0, ptr [[TMP1]], align 1 +; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 5) +; BE-NEXT: store i32 825373492, ptr [[DST]], align 1 +; BE-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 4 +; BE-NEXT: store i8 0, ptr [[TMP2]], align 1 +; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 5) +; BE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @a5, i64 5, i1 false) +; BE-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 5 +; BE-NEXT: store i8 0, ptr [[TMP3]], align 1 +; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 5) +; BE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @a5, i64 5, i1 false) +; BE-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 5 +; BE-NEXT: store i8 0, ptr [[TMP4]], align 1 +; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 5) ; BE-NEXT: ret void ; ; LE-LABEL: @fold_strlcpy_a5( -; LE-NEXT: call void @sink(i8* [[DST:%.*]], i64 5) -; LE-NEXT: store i8 0, i8* [[DST]], align 1 -; LE-NEXT: call void @sink(i8* nonnull [[DST]], i64 5) -; LE-NEXT: store i8 49, i8* [[DST]], align 1 -; LE-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, i8* [[DST]], i64 1 -; LE-NEXT: store i8 0, i8* [[TMP1]], align 1 -; LE-NEXT: call void @sink(i8* nonnull [[DST]], i64 5) -; LE-NEXT: [[TMP2:%.*]] = bitcast i8* [[DST]] to i32* -; LE-NEXT: store i32 875770417, i32* [[TMP2]], align 1 -; LE-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, i8* [[DST]], i64 4 -; LE-NEXT: store i8 0, i8* [[TMP3]], align 1 -; LE-NEXT: call void @sink(i8* nonnull [[DST]], i64 5) -; LE-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(5) [[DST]], i8* noundef nonnull align 1 dereferenceable(5) getelementptr inbounds ([5 x i8], [5 x i8]* @a5, i64 0, i64 0), i64 5, i1 false) -; LE-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, i8* [[DST]], i64 5 -; LE-NEXT: store i8 0, i8* [[TMP4]], align 1 -; LE-NEXT: call void @sink(i8* nonnull [[DST]], i64 5) -; LE-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(5) [[DST]], i8* noundef nonnull align 1 dereferenceable(5) getelementptr inbounds ([5 x i8], [5 x i8]* @a5, i64 0, i64 0), i64 5, i1 false) -; LE-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, i8* [[DST]], i64 5 -; LE-NEXT: store i8 0, i8* [[TMP5]], align 1 -; LE-NEXT: call void @sink(i8* nonnull [[DST]], i64 5) +; LE-NEXT: call void @sink(ptr [[DST:%.*]], i64 5) +; LE-NEXT: store i8 0, ptr [[DST]], align 1 +; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 5) +; LE-NEXT: store i8 49, ptr [[DST]], align 1 +; LE-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1 +; LE-NEXT: store i8 0, ptr [[TMP1]], align 1 +; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 5) +; LE-NEXT: store i32 875770417, ptr [[DST]], align 1 +; LE-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 4 +; LE-NEXT: store i8 0, ptr [[TMP2]], align 1 +; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 5) +; LE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @a5, i64 5, i1 false) +; LE-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 5 +; LE-NEXT: store i8 0, ptr [[TMP3]], align 1 +; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 5) +; LE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @a5, i64 5, i1 false) +; LE-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 5 +; LE-NEXT: store i8 0, ptr [[TMP4]], align 1 +; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 5) ; LE-NEXT: ret void ; - %pa5 = getelementptr [5 x i8], [5 x i8]* @a5, i32 0, i32 0 - %na5_0 = call i64 @strlcpy(i8* %dst, i8* %pa5, i64 0) - call void @sink(i8* %dst, i64 %na5_0) + %na5_0 = call i64 @strlcpy(ptr %dst, ptr @a5, i64 0) + call void @sink(ptr %dst, i64 %na5_0) - %na5_1 = call i64 @strlcpy(i8* %dst, i8* %pa5, i64 1) - call void @sink(i8* %dst, i64 %na5_1) + %na5_1 = call i64 @strlcpy(ptr %dst, ptr @a5, i64 1) + call void @sink(ptr %dst, i64 %na5_1) - %na5_2 = call i64 @strlcpy(i8* %dst, i8* %pa5, i64 2) - call void @sink(i8* %dst, i64 %na5_2) + %na5_2 = call i64 @strlcpy(ptr %dst, ptr @a5, i64 2) + call void @sink(ptr %dst, i64 %na5_2) - %na5_5 = call i64 @strlcpy(i8* %dst, i8* %pa5, i64 5) - call void @sink(i8* %dst, i64 %na5_5) + %na5_5 = call i64 @strlcpy(ptr %dst, ptr @a5, i64 5) + call void @sink(ptr %dst, i64 %na5_5) - %na5_6 = call i64 @strlcpy(i8* %dst, i8* %pa5, i64 6) - call void @sink(i8* %dst, i64 %na5_6) + %na5_6 = call i64 @strlcpy(ptr %dst, ptr @a5, i64 6) + call void @sink(ptr %dst, i64 %na5_6) - %na5_9 = call i64 @strlcpy(i8* %dst, i8* %pa5, i64 9) - call void @sink(i8* %dst, i64 %na5_9) + %na5_9 = call i64 @strlcpy(ptr %dst, ptr @a5, i64 9) + call void @sink(ptr %dst, i64 %na5_9) ret void } diff --git a/llvm/test/Transforms/InstCombine/strlen-1.ll b/llvm/test/Transforms/InstCombine/strlen-1.ll --- a/llvm/test/Transforms/InstCombine/strlen-1.ll +++ b/llvm/test/Transforms/InstCombine/strlen-1.ll @@ -13,7 +13,7 @@ @a = common global [32 x i8] zeroinitializer, align 1 @null_hello_mid = constant [13 x i8] c"hello wor\00ld\00" -declare i32 @strlen(i8*) +declare i32 @strlen(ptr) ; Check strlen(string constant) -> integer constant. @@ -21,8 +21,7 @@ ; CHECK-LABEL: @test_simplify1( ; CHECK-NEXT: ret i32 5 ; - %hello_p = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - %hello_l = call i32 @strlen(i8* %hello_p) + %hello_l = call i32 @strlen(ptr @hello) ret i32 %hello_l } @@ -30,8 +29,7 @@ ; CHECK-LABEL: @test_simplify2( ; CHECK-NEXT: ret i32 0 ; - %null_p = getelementptr [1 x i8], [1 x i8]* @null, i32 0, i32 0 - %null_l = call i32 @strlen(i8* %null_p) + %null_l = call i32 @strlen(ptr @null) ret i32 %null_l } @@ -39,8 +37,7 @@ ; CHECK-LABEL: @test_simplify3( ; CHECK-NEXT: ret i32 0 ; - %null_hello_p = getelementptr [7 x i8], [7 x i8]* @null_hello, i32 0, i32 0 - %null_hello_l = call i32 @strlen(i8* %null_hello_p) + %null_hello_l = call i32 @strlen(ptr @null_hello) ret i32 %null_hello_l } @@ -48,7 +45,7 @@ ; CHECK-LABEL: @test_simplify4( ; CHECK-NEXT: ret i32 0 ; - %len = tail call i32 @strlen(i8* @nullstring) nounwind + %len = tail call i32 @strlen(ptr @nullstring) nounwind ret i32 %len } @@ -58,19 +55,18 @@ ; CHECK-LABEL: @test_simplify5( ; CHECK-NEXT: ret i1 false ; - %hello_p = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - %hello_l = call i32 @strlen(i8* %hello_p) + %hello_l = call i32 @strlen(ptr @hello) %eq_hello = icmp eq i32 %hello_l, 0 ret i1 %eq_hello } -define i1 @test_simplify6(i8* %str_p) { +define i1 @test_simplify6(ptr %str_p) { ; CHECK-LABEL: @test_simplify6( -; CHECK-NEXT: [[STRLENFIRST:%.*]] = load i8, i8* [[STR_P:%.*]], align 1 -; CHECK-NEXT: [[EQ_NULL:%.*]] = icmp eq i8 [[STRLENFIRST]], 0 +; CHECK-NEXT: [[CHAR0:%.*]] = load i8, ptr [[STR_P:%.*]], align 1 +; CHECK-NEXT: [[EQ_NULL:%.*]] = icmp eq i8 [[CHAR0]], 0 ; CHECK-NEXT: ret i1 [[EQ_NULL]] ; - %str_l = call i32 @strlen(i8* %str_p) + %str_l = call i32 @strlen(ptr %str_p) %eq_null = icmp eq i32 %str_l, 0 ret i1 %eq_null } @@ -81,19 +77,18 @@ ; CHECK-LABEL: @test_simplify7( ; CHECK-NEXT: ret i1 true ; - %hello_p = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - %hello_l = call i32 @strlen(i8* %hello_p) + %hello_l = call i32 @strlen(ptr @hello) %ne_hello = icmp ne i32 %hello_l, 0 ret i1 %ne_hello } -define i1 @test_simplify8(i8* %str_p) { +define i1 @test_simplify8(ptr %str_p) { ; CHECK-LABEL: @test_simplify8( -; CHECK-NEXT: [[STRLENFIRST:%.*]] = load i8, i8* [[STR_P:%.*]], align 1 -; CHECK-NEXT: [[NE_NULL:%.*]] = icmp ne i8 [[STRLENFIRST]], 0 +; CHECK-NEXT: [[CHAR0:%.*]] = load i8, ptr [[STR_P:%.*]], align 1 +; CHECK-NEXT: [[NE_NULL:%.*]] = icmp ne i8 [[CHAR0]], 0 ; CHECK-NEXT: ret i1 [[NE_NULL]] ; - %str_l = call i32 @strlen(i8* %str_p) + %str_l = call i32 @strlen(ptr %str_p) %ne_null = icmp ne i32 %str_l, 0 ret i1 %ne_null } @@ -103,10 +98,8 @@ ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[X:%.*]], i32 5, i32 6 ; CHECK-NEXT: ret i32 [[TMP1]] ; - %hello = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - %longer = getelementptr [7 x i8], [7 x i8]* @longer, i32 0, i32 0 - %s = select i1 %x, i8* %hello, i8* %longer - %l = call i32 @strlen(i8* %s) + %s = select i1 %x, ptr @hello, ptr @longer + %l = call i32 @strlen(ptr %s) ret i32 %l } @@ -118,8 +111,8 @@ ; CHECK-NEXT: [[TMP1:%.*]] = sub i32 5, [[X:%.*]] ; CHECK-NEXT: ret i32 [[TMP1]] ; - %hello_p = getelementptr inbounds [6 x i8], [6 x i8]* @hello, i32 0, i32 %x - %hello_l = call i32 @strlen(i8* %hello_p) + %hello_p = getelementptr inbounds [6 x i8], ptr @hello, i32 0, i32 %x + %hello_l = call i32 @strlen(ptr %hello_p) ret i32 %hello_l } @@ -128,8 +121,8 @@ ; CHECK-NEXT: [[TMP1:%.*]] = sub i32 5, [[X:%.*]] ; CHECK-NEXT: ret i32 [[TMP1]] ; - %hello_p = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 %x - %hello_l = call i32 @strlen(i8* %hello_p) + %hello_p = getelementptr [6 x i8], ptr @hello, i32 0, i32 %x + %hello_l = call i32 @strlen(ptr %hello_p) ret i32 %hello_l } @@ -142,8 +135,8 @@ ; CHECK-NEXT: ret i32 [[TMP1]] ; %and = and i32 %x, 7 - %hello_p = getelementptr inbounds [13 x i8], [13 x i8]* @null_hello_mid, i32 0, i32 %and - %hello_l = call i32 @strlen(i8* %hello_p) + %hello_p = getelementptr inbounds [13 x i8], ptr @null_hello_mid, i32 0, i32 %and + %hello_l = call i32 @strlen(ptr %hello_p) ret i32 %hello_l } @@ -151,11 +144,10 @@ define i32 @test_no_simplify1() { ; CHECK-LABEL: @test_no_simplify1( -; CHECK-NEXT: [[A_L:%.*]] = call i32 @strlen(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0)) +; CHECK-NEXT: [[A_L:%.*]] = call i32 @strlen(ptr noundef nonnull @a) ; CHECK-NEXT: ret i32 [[A_L]] ; - %a_p = getelementptr [32 x i8], [32 x i8]* @a, i32 0, i32 0 - %a_l = call i32 @strlen(i8* %a_p) + %a_l = call i32 @strlen(ptr @a) ret i32 %a_l } @@ -163,23 +155,23 @@ define i32 @test_no_simplify2(i32 %x) { ; CHECK-LABEL: @test_no_simplify2( -; CHECK-NEXT: [[HELLO_P:%.*]] = getelementptr inbounds [7 x i8], [7 x i8]* @null_hello, i32 0, i32 [[X:%.*]] -; CHECK-NEXT: [[HELLO_L:%.*]] = call i32 @strlen(i8* noundef nonnull [[HELLO_P]]) +; CHECK-NEXT: [[HELLO_P:%.*]] = getelementptr inbounds [7 x i8], ptr @null_hello, i32 0, i32 [[X:%.*]] +; CHECK-NEXT: [[HELLO_L:%.*]] = call i32 @strlen(ptr noundef nonnull [[HELLO_P]]) ; CHECK-NEXT: ret i32 [[HELLO_L]] ; - %hello_p = getelementptr inbounds [7 x i8], [7 x i8]* @null_hello, i32 0, i32 %x - %hello_l = call i32 @strlen(i8* %hello_p) + %hello_p = getelementptr inbounds [7 x i8], ptr @null_hello, i32 0, i32 %x + %hello_l = call i32 @strlen(ptr %hello_p) ret i32 %hello_l } define i32 @test_no_simplify2_no_null_opt(i32 %x) #0 { ; CHECK-LABEL: @test_no_simplify2_no_null_opt( -; CHECK-NEXT: [[HELLO_P:%.*]] = getelementptr inbounds [7 x i8], [7 x i8]* @null_hello, i32 0, i32 [[X:%.*]] -; CHECK-NEXT: [[HELLO_L:%.*]] = call i32 @strlen(i8* noundef [[HELLO_P]]) +; CHECK-NEXT: [[HELLO_P:%.*]] = getelementptr inbounds [7 x i8], ptr @null_hello, i32 0, i32 [[X:%.*]] +; CHECK-NEXT: [[HELLO_L:%.*]] = call i32 @strlen(ptr noundef [[HELLO_P]]) ; CHECK-NEXT: ret i32 [[HELLO_L]] ; - %hello_p = getelementptr inbounds [7 x i8], [7 x i8]* @null_hello, i32 0, i32 %x - %hello_l = call i32 @strlen(i8* %hello_p) + %hello_p = getelementptr inbounds [7 x i8], ptr @null_hello, i32 0, i32 %x + %hello_l = call i32 @strlen(ptr %hello_p) ret i32 %hello_l } @@ -188,94 +180,94 @@ define i32 @test_no_simplify3(i32 %x) { ; CHECK-LABEL: @test_no_simplify3( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 15 -; CHECK-NEXT: [[HELLO_P:%.*]] = getelementptr inbounds [13 x i8], [13 x i8]* @null_hello_mid, i32 0, i32 [[AND]] -; CHECK-NEXT: [[HELLO_L:%.*]] = call i32 @strlen(i8* noundef nonnull [[HELLO_P]]) +; CHECK-NEXT: [[HELLO_P:%.*]] = getelementptr inbounds [13 x i8], ptr @null_hello_mid, i32 0, i32 [[AND]] +; CHECK-NEXT: [[HELLO_L:%.*]] = call i32 @strlen(ptr noundef nonnull [[HELLO_P]]) ; CHECK-NEXT: ret i32 [[HELLO_L]] ; %and = and i32 %x, 15 - %hello_p = getelementptr inbounds [13 x i8], [13 x i8]* @null_hello_mid, i32 0, i32 %and - %hello_l = call i32 @strlen(i8* %hello_p) + %hello_p = getelementptr inbounds [13 x i8], ptr @null_hello_mid, i32 0, i32 %and + %hello_l = call i32 @strlen(ptr %hello_p) ret i32 %hello_l } define i32 @test_no_simplify3_on_null_opt(i32 %x) #0 { ; CHECK-LABEL: @test_no_simplify3_on_null_opt( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 15 -; CHECK-NEXT: [[HELLO_P:%.*]] = getelementptr inbounds [13 x i8], [13 x i8]* @null_hello_mid, i32 0, i32 [[AND]] -; CHECK-NEXT: [[HELLO_L:%.*]] = call i32 @strlen(i8* noundef [[HELLO_P]]) +; CHECK-NEXT: [[HELLO_P:%.*]] = getelementptr inbounds [13 x i8], ptr @null_hello_mid, i32 0, i32 [[AND]] +; CHECK-NEXT: [[HELLO_L:%.*]] = call i32 @strlen(ptr noundef [[HELLO_P]]) ; CHECK-NEXT: ret i32 [[HELLO_L]] ; %and = and i32 %x, 15 - %hello_p = getelementptr inbounds [13 x i8], [13 x i8]* @null_hello_mid, i32 0, i32 %and - %hello_l = call i32 @strlen(i8* %hello_p) + %hello_p = getelementptr inbounds [13 x i8], ptr @null_hello_mid, i32 0, i32 %and + %hello_l = call i32 @strlen(ptr %hello_p) ret i32 %hello_l } -define i32 @test1(i8* %str) { +define i32 @test1(ptr %str) { ; CHECK-LABEL: @test1( -; CHECK-NEXT: [[LEN:%.*]] = tail call i32 @strlen(i8* noundef nonnull dereferenceable(1) [[STR:%.*]]) #[[ATTR1:[0-9]+]] +; CHECK-NEXT: [[LEN:%.*]] = tail call i32 @strlen(ptr noundef nonnull dereferenceable(1) [[STR:%.*]]) #[[ATTR1:[0-9]+]] ; CHECK-NEXT: ret i32 [[LEN]] ; - %len = tail call i32 @strlen(i8* %str) nounwind + %len = tail call i32 @strlen(ptr %str) nounwind ret i32 %len } -define i32 @test2(i8* %str) #0 { +define i32 @test2(ptr %str) #0 { ; CHECK-LABEL: @test2( -; CHECK-NEXT: [[LEN:%.*]] = tail call i32 @strlen(i8* noundef [[STR:%.*]]) #[[ATTR1]] +; CHECK-NEXT: [[LEN:%.*]] = tail call i32 @strlen(ptr noundef [[STR:%.*]]) #[[ATTR1]] ; CHECK-NEXT: ret i32 [[LEN]] ; - %len = tail call i32 @strlen(i8* %str) nounwind + %len = tail call i32 @strlen(ptr %str) nounwind ret i32 %len } ; Test cases for PR47149. define i1 @strlen0_after_write_to_first_byte_global() { ; CHECK-LABEL: @strlen0_after_write_to_first_byte_global( -; CHECK-NEXT: store i8 49, i8* getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0), align 16 +; CHECK-NEXT: store i8 49, ptr @a, align 16 ; CHECK-NEXT: ret i1 false ; - store i8 49, i8* getelementptr inbounds ([32 x i8], [32 x i8]* @a, i64 0, i64 0), align 16 - %len = tail call i32 @strlen(i8* nonnull dereferenceable(1) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i64 0, i64 0)) + store i8 49, ptr @a, align 16 + %len = tail call i32 @strlen(ptr nonnull dereferenceable(1) @a) %cmp = icmp eq i32 %len, 0 ret i1 %cmp } define i1 @strlen0_after_write_to_second_byte_global() { ; CHECK-LABEL: @strlen0_after_write_to_second_byte_global( -; CHECK-NEXT: store i8 49, i8* getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 1), align 16 -; CHECK-NEXT: [[STRLENFIRST:%.*]] = load i8, i8* getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0), align 1 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[STRLENFIRST]], 0 +; CHECK-NEXT: store i8 49, ptr getelementptr inbounds ([32 x i8], ptr @a, i32 0, i32 1), align 16 +; CHECK-NEXT: [[CHAR0:%.*]] = load i8, ptr @a, align 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[CHAR0]], 0 ; CHECK-NEXT: ret i1 [[CMP]] ; - store i8 49, i8* getelementptr inbounds ([32 x i8], [32 x i8]* @a, i64 0, i64 1), align 16 - %len = tail call i32 @strlen(i8* nonnull dereferenceable(1) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i64 0, i64 0)) + store i8 49, ptr getelementptr inbounds ([32 x i8], ptr @a, i64 0, i64 1), align 16 + %len = tail call i32 @strlen(ptr nonnull dereferenceable(1) @a) %cmp = icmp eq i32 %len, 0 ret i1 %cmp } -define i1 @strlen0_after_write_to_first_byte(i8 *%ptr) { +define i1 @strlen0_after_write_to_first_byte(ptr %ptr) { ; CHECK-LABEL: @strlen0_after_write_to_first_byte( -; CHECK-NEXT: store i8 49, i8* [[PTR:%.*]], align 1 +; CHECK-NEXT: store i8 49, ptr [[PTR:%.*]], align 1 ; CHECK-NEXT: ret i1 false ; - store i8 49, i8* %ptr - %len = tail call i32 @strlen(i8* nonnull dereferenceable(1) %ptr) + store i8 49, ptr %ptr + %len = tail call i32 @strlen(ptr nonnull dereferenceable(1) %ptr) %cmp = icmp eq i32 %len, 0 ret i1 %cmp } -define i1 @strlen0_after_write_to_second_byte(i8 *%ptr) { +define i1 @strlen0_after_write_to_second_byte(ptr %ptr) { ; CHECK-LABEL: @strlen0_after_write_to_second_byte( -; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, i8* [[PTR:%.*]], i32 1 -; CHECK-NEXT: store i8 49, i8* [[GEP]], align 1 -; CHECK-NEXT: [[STRLENFIRST:%.*]] = load i8, i8* [[PTR]], align 1 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[STRLENFIRST]], 0 +; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[PTR:%.*]], i32 1 +; CHECK-NEXT: store i8 49, ptr [[GEP]], align 1 +; CHECK-NEXT: [[CHAR0:%.*]] = load i8, ptr [[PTR]], align 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[CHAR0]], 0 ; CHECK-NEXT: ret i1 [[CMP]] ; - %gep = getelementptr i8, i8* %ptr, i64 1 - store i8 49, i8* %gep - %len = tail call i32 @strlen(i8* nonnull dereferenceable(1) %ptr) + %gep = getelementptr i8, ptr %ptr, i64 1 + store i8 49, ptr %gep + %len = tail call i32 @strlen(ptr nonnull dereferenceable(1) %ptr) %cmp = icmp eq i32 %len, 0 ret i1 %cmp } diff --git a/llvm/test/Transforms/InstCombine/strlen-2.ll b/llvm/test/Transforms/InstCombine/strlen-2.ll --- a/llvm/test/Transforms/InstCombine/strlen-2.ll +++ b/llvm/test/Transforms/InstCombine/strlen-2.ll @@ -7,14 +7,13 @@ @hello = constant [6 x i8] c"hello\00" -declare i32 @strlen(i8*, i32) +declare i32 @strlen(ptr, i32) define i32 @test_no_simplify1() { ; CHECK-LABEL: @test_no_simplify1( -; CHECK-NEXT: [[HELLO_L:%.*]] = call i32 @strlen(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 187) +; CHECK-NEXT: [[HELLO_L:%.*]] = call i32 @strlen(ptr nonnull @hello, i32 187) ; CHECK-NEXT: ret i32 [[HELLO_L]] ; - %hello_p = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - %hello_l = call i32 @strlen(i8* %hello_p, i32 187) + %hello_l = call i32 @strlen(ptr @hello, i32 187) ret i32 %hello_l } diff --git a/llvm/test/Transforms/InstCombine/strlen-4.ll b/llvm/test/Transforms/InstCombine/strlen-4.ll --- a/llvm/test/Transforms/InstCombine/strlen-4.ll +++ b/llvm/test/Transforms/InstCombine/strlen-4.ll @@ -4,7 +4,7 @@ ; ; RUN: opt < %s -passes=instcombine -S | FileCheck %s -declare i64 @strlen(i8*) +declare i64 @strlen(ptr) @sx = external global [0 x i8] @s3 = constant [4 x i8] c"123\00" @@ -18,16 +18,15 @@ define i64 @fold_strlen_s3_pi_s5(i1 %X, i64 %I) { ; CHECK-LABEL: @fold_strlen_s3_pi_s5( -; CHECK-NEXT: [[PS3_PI:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* @s3, i64 0, i64 [[I:%.*]] -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[X:%.*]], i8* [[PS3_PI]], i8* getelementptr inbounds ([6 x i8], [6 x i8]* @s5, i64 0, i64 0) -; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strlen(i8* noundef nonnull dereferenceable(1) [[SEL]]) +; CHECK-NEXT: [[PS3_PI:%.*]] = getelementptr inbounds [4 x i8], ptr @s3, i64 0, i64 [[I:%.*]] +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[X:%.*]], ptr [[PS3_PI]], ptr @s5 +; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strlen(ptr noundef nonnull [[SEL]]) ; CHECK-NEXT: ret i64 [[LEN]] ; - %ps3_pi = getelementptr inbounds [4 x i8], [4 x i8]* @s3, i64 0, i64 %I - %ps5 = getelementptr [6 x i8], [6 x i8]* @s5, i64 0, i64 0 - %sel = select i1 %X, i8* %ps3_pi, i8* %ps5 - %len = tail call i64 @strlen(i8* %sel) + %ps3_pi = getelementptr inbounds [4 x i8], ptr @s3, i64 0, i64 %I + %sel = select i1 %X, ptr %ps3_pi, ptr @s5 + %len = tail call i64 @strlen(ptr %sel) ret i64 %len } @@ -41,18 +40,17 @@ ; XFAIL-CHECK-NEXT: [[SEL:%.*]] = select i1 %0, i64 [[DIF_I]], i64 5 ; XFAIL-CHECK-NEXT: ret i64 [[SEL]] ; CHECK-LABEL: @fold_strlen_s3_pi_p1_s5( -; CHECK-NEXT: [[PS3_PI:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* @s3, i64 0, i64 [[TMP1:%.*]] -; CHECK-NEXT: [[PS3_PI_P1:%.*]] = getelementptr i8, i8* [[PS3_PI]], i64 1 -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[TMP0:%.*]], i8* [[PS3_PI_P1]], i8* getelementptr inbounds ([6 x i8], [6 x i8]* @s5, i64 0, i64 0) -; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strlen(i8* noundef nonnull dereferenceable(1) [[SEL]]) +; CHECK-NEXT: [[PS3_PI:%.*]] = getelementptr inbounds [4 x i8], ptr @s3, i64 0, i64 [[TMP1:%.*]] +; CHECK-NEXT: [[PS3_PI_P1:%.*]] = getelementptr i8, ptr [[PS3_PI]], i64 1 +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[TMP0:%.*]], ptr [[PS3_PI_P1]], ptr @s5 +; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strlen(ptr noundef nonnull dereferenceable(1) [[SEL]]) ; CHECK-NEXT: ret i64 [[LEN]] ; - %ps3_pi = getelementptr inbounds [4 x i8], [4 x i8]* @s3, i64 0, i64 %1 - %ps3_pi_p1 = getelementptr i8, i8* %ps3_pi, i64 1 - %ps5 = getelementptr [6 x i8], [6 x i8]* @s5, i64 0, i64 0 - %sel = select i1 %0, i8* %ps3_pi_p1, i8* %ps5 - %len = tail call i64 @strlen(i8* %sel) + %ps3_pi = getelementptr inbounds [4 x i8], ptr @s3, i64 0, i64 %1 + %ps3_pi_p1 = getelementptr i8, ptr %ps3_pi, i64 1 + %sel = select i1 %0, ptr %ps3_pi_p1, ptr @s5 + %len = tail call i64 @strlen(ptr %sel) ret i64 %len } @@ -63,16 +61,15 @@ define i64 @call_strlen_s5_3_pi_s5(i1 %0, i64 %1) { ; CHECK-LABEL: @call_strlen_s5_3_pi_s5( -; CHECK-NEXT: [[PS5_3_PI:%.*]] = getelementptr inbounds [10 x i8], [10 x i8]* @s5_3, i64 0, i64 [[TMP1:%.*]] -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[TMP0:%.*]], i8* [[PS5_3_PI]], i8* getelementptr inbounds ([6 x i8], [6 x i8]* @s5, i64 0, i64 0) -; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strlen(i8* noundef nonnull dereferenceable(1) [[SEL]]) +; CHECK-NEXT: [[PS5_3_PI:%.*]] = getelementptr inbounds [10 x i8], ptr @s5_3, i64 0, i64 [[TMP1:%.*]] +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[TMP0:%.*]], ptr [[PS5_3_PI]], ptr @s5 +; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strlen(ptr noundef nonnull [[SEL]]) ; CHECK-NEXT: ret i64 [[LEN]] ; - %ps5_3_pi = getelementptr inbounds [10 x i8], [10 x i8]* @s5_3, i64 0, i64 %1 - %ps5 = getelementptr [6 x i8], [6 x i8]* @s5, i64 0, i64 0 - %sel = select i1 %0, i8* %ps5_3_pi, i8* %ps5 - %len = tail call i64 @strlen(i8* %sel) + %ps5_3_pi = getelementptr inbounds [10 x i8], ptr @s5_3, i64 0, i64 %1 + %sel = select i1 %0, ptr %ps5_3_pi, ptr @s5 + %len = tail call i64 @strlen(ptr %sel) ret i64 %len } @@ -81,16 +78,15 @@ define i64 @call_strlen_s5_3_s5_pj(i1 %X, i64 %J) { ; CHECK-LABEL: @call_strlen_s5_3_s5_pj( -; CHECK-NEXT: [[PS5:%.*]] = getelementptr inbounds [6 x i8], [6 x i8]* @s5, i64 0, i64 [[J:%.*]] -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[X:%.*]], i8* getelementptr inbounds ([10 x i8], [10 x i8]* @s5_3, i64 0, i64 0), i8* [[PS5]] -; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strlen(i8* noundef nonnull dereferenceable(1) [[SEL]]) +; CHECK-NEXT: [[PS5:%.*]] = getelementptr inbounds [6 x i8], ptr @s5, i64 0, i64 [[J:%.*]] +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[X:%.*]], ptr @s5_3, ptr [[PS5]] +; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strlen(ptr noundef nonnull [[SEL]]) ; CHECK-NEXT: ret i64 [[LEN]] ; - %ps5_3_pi = getelementptr [10 x i8], [10 x i8]* @s5_3, i64 0, i64 0 - %ps5 = getelementptr inbounds [6 x i8], [6 x i8]* @s5, i64 0, i64 %J - %sel = select i1 %X, i8* %ps5_3_pi, i8* %ps5 - %len = tail call i64 @strlen(i8* %sel) + %ps5 = getelementptr inbounds [6 x i8], ptr @s5, i64 0, i64 %J + %sel = select i1 %X, ptr @s5_3, ptr %ps5 + %len = tail call i64 @strlen(ptr %sel) ret i64 %len } @@ -99,16 +95,15 @@ define i64 @fold_strlen_s3_s5_pj(i1 %X, i64 %J) { ; CHECK-LABEL: @fold_strlen_s3_s5_pj( -; CHECK-NEXT: [[PS5_PJ:%.*]] = getelementptr inbounds [6 x i8], [6 x i8]* @s5, i64 0, i64 [[J:%.*]] -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[X:%.*]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* [[PS5_PJ]] -; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strlen(i8* noundef nonnull dereferenceable(1) [[SEL]]) +; CHECK-NEXT: [[PS5_PJ:%.*]] = getelementptr inbounds [6 x i8], ptr @s5, i64 0, i64 [[J:%.*]] +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[X:%.*]], ptr @s3, ptr [[PS5_PJ]] +; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strlen(ptr noundef nonnull [[SEL]]) ; CHECK-NEXT: ret i64 [[LEN]] ; - %ps3 = getelementptr [4 x i8], [4 x i8]* @s3, i64 0, i64 0 - %ps5_pj = getelementptr inbounds [6 x i8], [6 x i8]* @s5, i64 0, i64 %J - %sel = select i1 %X, i8* %ps3, i8* %ps5_pj - %len = tail call i64 @strlen(i8* %sel) + %ps5_pj = getelementptr inbounds [6 x i8], ptr @s5, i64 0, i64 %J + %sel = select i1 %X, ptr @s3, ptr %ps5_pj + %len = tail call i64 @strlen(ptr %sel) ret i64 %len } @@ -119,16 +114,15 @@ define i64 @call_strlen_s3_s5_3_pj(i1 %0, i64 %1) { ; CHECK-LABEL: @call_strlen_s3_s5_3_pj( -; CHECK-NEXT: [[PS5_3_PJ:%.*]] = getelementptr inbounds [10 x i8], [10 x i8]* @s5_3, i64 0, i64 [[TMP1:%.*]] -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[TMP0:%.*]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* [[PS5_3_PJ]] -; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strlen(i8* noundef nonnull dereferenceable(1) [[SEL]]) +; CHECK-NEXT: [[PS5_3_PJ:%.*]] = getelementptr inbounds [10 x i8], ptr @s5_3, i64 0, i64 [[TMP1:%.*]] +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[TMP0:%.*]], ptr @s3, ptr [[PS5_3_PJ]] +; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strlen(ptr noundef nonnull [[SEL]]) ; CHECK-NEXT: ret i64 [[LEN]] ; - %ps3 = getelementptr [4 x i8], [4 x i8]* @s3, i64 0, i64 0 - %ps5_3_pj = getelementptr inbounds [10 x i8], [10 x i8]* @s5_3, i64 0, i64 %1 - %sel = select i1 %0, i8* %ps3, i8* %ps5_3_pj - %len = tail call i64 @strlen(i8* %sel) + %ps5_3_pj = getelementptr inbounds [10 x i8], ptr @s5_3, i64 0, i64 %1 + %sel = select i1 %0, ptr @s3, ptr %ps5_3_pj + %len = tail call i64 @strlen(ptr %sel) ret i64 %len } @@ -137,19 +131,19 @@ define i64 @fold_strlen_s3_pi_s5_pj(i1 %X, i64 %I, i64 %J) { ; CHECK-LABEL: @fold_strlen_s3_pi_s5_pj( -; CHECK-NEXT: [[PS3_PI:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* @s3, i64 0, i64 [[I:%.*]] -; CHECK-NEXT: [[PS5_PJ:%.*]] = getelementptr inbounds [6 x i8], [6 x i8]* @s5, i64 0, i64 [[J:%.*]] -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[X:%.*]], i8* [[PS3_PI]], i8* [[PS5_PJ]] -; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strlen(i8* noundef nonnull [[SEL]]) +; CHECK-NEXT: [[PS3_PI:%.*]] = getelementptr inbounds [4 x i8], ptr @s3, i64 0, i64 [[I:%.*]] +; CHECK-NEXT: [[PS5_PJ:%.*]] = getelementptr inbounds [6 x i8], ptr @s5, i64 0, i64 [[J:%.*]] +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[X:%.*]], ptr [[PS3_PI]], ptr [[PS5_PJ]] +; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strlen(ptr noundef nonnull [[SEL]]) ; CHECK-NEXT: ret i64 [[LEN]] ; ; Use CHECK-DAG since the two instructions below might be emitted in reverse ; order. - %ps3_pi = getelementptr inbounds [4 x i8], [4 x i8]* @s3, i64 0, i64 %I - %ps5_pj = getelementptr inbounds [6 x i8], [6 x i8]* @s5, i64 0, i64 %J - %sel = select i1 %X, i8* %ps3_pi, i8* %ps5_pj - %len = tail call i64 @strlen(i8* %sel) + %ps3_pi = getelementptr inbounds [4 x i8], ptr @s3, i64 0, i64 %I + %ps5_pj = getelementptr inbounds [6 x i8], ptr @s5, i64 0, i64 %J + %sel = select i1 %X, ptr %ps3_pi, ptr %ps5_pj + %len = tail call i64 @strlen(ptr %sel) ret i64 %len } @@ -161,17 +155,17 @@ ; CHECK-LABEL: @fold_strlen_s3_s5_s7( ; CHECK-NEXT: [[X_EQ_3:%.*]] = icmp eq i32 [[X:%.*]], 3 ; CHECK-NEXT: [[X_EQ_5:%.*]] = icmp eq i32 [[X]], 5 -; CHECK-NEXT: [[SEL_X_EQ_5:%.*]] = select i1 [[X_EQ_5]], i8* getelementptr inbounds ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @s7, i64 0, i64 0) -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[X_EQ_3]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* [[SEL_X_EQ_5]] -; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strlen(i8* noundef nonnull dereferenceable(1) [[SEL]]) +; CHECK-NEXT: [[SEL_X_EQ_5:%.*]] = select i1 [[X_EQ_5]], ptr @s5, ptr @s7 +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[X_EQ_3]], ptr @s3, ptr [[SEL_X_EQ_5]] +; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strlen(ptr noundef nonnull [[SEL]]) ; CHECK-NEXT: ret i64 [[LEN]] ; %x_eq_3 = icmp eq i32 %X, 3 %x_eq_5 = icmp eq i32 %X, 5 - %sel_x_eq_5 = select i1 %x_eq_5, i8* getelementptr ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i8* getelementptr ([8 x i8], [8 x i8]* @s7, i64 0, i64 0) - %sel = select i1 %x_eq_3, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* %sel_x_eq_5 - %len = tail call i64 @strlen(i8* %sel) + %sel_x_eq_5 = select i1 %x_eq_5, ptr @s5, ptr @s7 + %sel = select i1 %x_eq_3, ptr @s3, ptr %sel_x_eq_5 + %len = tail call i64 @strlen(ptr %sel) ret i64 %len } @@ -182,16 +176,16 @@ ; CHECK-LABEL: @call_strlen_sx_s5_s7( ; CHECK-NEXT: [[X_EQ_3:%.*]] = icmp eq i32 [[X:%.*]], 3 ; CHECK-NEXT: [[X_EQ_5:%.*]] = icmp eq i32 [[X]], 5 -; CHECK-NEXT: [[SEL_X_EQ_5:%.*]] = select i1 [[X_EQ_5]], i8* getelementptr inbounds ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @s7, i64 0, i64 0) -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[X_EQ_3]], i8* getelementptr inbounds ([0 x i8], [0 x i8]* @sx, i64 0, i64 0), i8* [[SEL_X_EQ_5]] -; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strlen(i8* noundef nonnull dereferenceable(1) [[SEL]]) +; CHECK-NEXT: [[SEL_X_EQ_5:%.*]] = select i1 [[X_EQ_5]], ptr @s5, ptr @s7 +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[X_EQ_3]], ptr @sx, ptr [[SEL_X_EQ_5]] +; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strlen(ptr noundef nonnull [[SEL]]) ; CHECK-NEXT: ret i64 [[LEN]] ; %x_eq_3 = icmp eq i32 %X, 3 %x_eq_5 = icmp eq i32 %X, 5 - %sel_x_eq_5 = select i1 %x_eq_5, i8* getelementptr ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i8* getelementptr ([8 x i8], [8 x i8]* @s7, i64 0, i64 0) - %sel = select i1 %x_eq_3, i8* getelementptr inbounds ([0 x i8], [0 x i8]* @sx, i64 0, i64 0), i8* %sel_x_eq_5 - %len = tail call i64 @strlen(i8* %sel) + %sel_x_eq_5 = select i1 %x_eq_5, ptr @s5, ptr @s7 + %sel = select i1 %x_eq_3, ptr @sx, ptr %sel_x_eq_5 + %len = tail call i64 @strlen(ptr %sel) ret i64 %len } diff --git a/llvm/test/Transforms/InstCombine/strncat-2.ll b/llvm/test/Transforms/InstCombine/strncat-2.ll --- a/llvm/test/Transforms/InstCombine/strncat-2.ll +++ b/llvm/test/Transforms/InstCombine/strncat-2.ll @@ -8,19 +8,17 @@ @hello = constant [6 x i8] c"hello\00" @empty = constant [1 x i8] c"\00" @a = common global [32 x i8] zeroinitializer, align 1 -declare i8* @strncat(i8*, i8*, i32) +declare ptr @strncat(ptr, ptr, i32) define void @test_simplify1() { ; CHECK-LABEL: @test_simplify1( -; CHECK-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0)) -; CHECK-NEXT: [[ENDPTR:%.*]] = getelementptr inbounds [32 x i8], [32 x i8]* @a, i32 0, i32 [[STRLEN]] -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(6) [[ENDPTR]], i8* noundef nonnull align 1 dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 6, i1 false) +; CHECK-NEXT: [[STRLEN:%.*]] = call i32 @strlen(ptr noundef nonnull @a) +; CHECK-NEXT: [[ENDPTR:%.*]] = getelementptr inbounds i8, ptr @a, i32 [[STRLEN]] +; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr noundef nonnull align 1 dereferenceable(6) [[ENDPTR]], ptr noundef nonnull align 1 dereferenceable(6) @hello, i32 6, i1 false) ; CHECK-NEXT: ret void ; - %dst = getelementptr [32 x i8], [32 x i8]* @a, i32 0, i32 0 - %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - call i8* @strncat(i8* %dst, i8* %src, i32 13) + call ptr @strncat(ptr @a, ptr @hello, i32 13) ret void } @@ -29,9 +27,7 @@ ; CHECK-NEXT: ret void ; - %dst = getelementptr [32 x i8], [32 x i8]* @a, i32 0, i32 0 - %src = getelementptr [1 x i8], [1 x i8]* @empty, i32 0, i32 0 - call i8* @strncat(i8* %dst, i8* %src, i32 13) + call ptr @strncat(ptr @a, ptr @empty, i32 13) ret void } @@ -40,74 +36,69 @@ ; CHECK-NEXT: ret void ; - %dst = getelementptr [32 x i8], [32 x i8]* @a, i32 0, i32 0 - %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - call i8* @strncat(i8* %dst, i8* %src, i32 0) + call ptr @strncat(ptr @a, ptr @hello, i32 0) ret void } define void @test_nosimplify1() { ; CHECK-LABEL: @test_nosimplify1( -; CHECK-NEXT: [[TMP1:%.*]] = call i8* @strncat(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0), i8* noundef nonnull dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 1) +; CHECK-NEXT: [[TMP1:%.*]] = call ptr @strncat(ptr noundef nonnull @a, ptr noundef nonnull dereferenceable(6) @hello, i32 1) ; CHECK-NEXT: ret void ; - %dst = getelementptr [32 x i8], [32 x i8]* @a, i32 0, i32 0 - %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - call i8* @strncat(i8* %dst, i8* %src, i32 1) + call ptr @strncat(ptr @a, ptr @hello, i32 1) ret void } ; strncat(nonnull x, nonnull y, n) -> strncat(nonnull x, y, n) -define i8* @test1(i8* %str1, i8* %str2, i32 %n) { +define ptr @test1(ptr %str1, ptr %str2, i32 %n) { ; CHECK-LABEL: @test1( -; CHECK-NEXT: [[TEMP1:%.*]] = call i8* @strncat(i8* noundef nonnull [[STR1:%.*]], i8* nonnull [[STR2:%.*]], i32 [[N:%.*]]) -; CHECK-NEXT: ret i8* [[TEMP1]] +; CHECK-NEXT: [[TEMP1:%.*]] = call ptr @strncat(ptr noundef nonnull [[STR1:%.*]], ptr nonnull [[STR2:%.*]], i32 [[N:%.*]]) +; CHECK-NEXT: ret ptr [[TEMP1]] ; - %temp1 = call i8* @strncat(i8* nonnull %str1, i8* nonnull %str2, i32 %n) - ret i8* %temp1 + %temp1 = call ptr @strncat(ptr nonnull %str1, ptr nonnull %str2, i32 %n) + ret ptr %temp1 } ; strncat(x, y, 0) -> x -define i8* @test2(i8* %str1, i8* %str2, i32 %n) { +define ptr @test2(ptr %str1, ptr %str2, i32 %n) { ; CHECK-LABEL: @test2( -; CHECK-NEXT: ret i8* [[STR1:%.*]] +; CHECK-NEXT: ret ptr [[STR1:%.*]] ; - %temp1 = call i8* @strncat(i8* %str1, i8* %str2, i32 0) - ret i8* %temp1 + %temp1 = call ptr @strncat(ptr %str1, ptr %str2, i32 0) + ret ptr %temp1 } ; strncat(x, y, 5) -> strncat(nonnull x, nonnull y, 5) -define i8* @test3(i8* %str1, i8* %str2, i32 %n) { +define ptr @test3(ptr %str1, ptr %str2, i32 %n) { ; CHECK-LABEL: @test3( -; CHECK-NEXT: [[TEMP1:%.*]] = call i8* @strncat(i8* noundef nonnull dereferenceable(1) [[STR1:%.*]], i8* noundef nonnull dereferenceable(1) [[STR2:%.*]], i32 5) -; CHECK-NEXT: ret i8* [[TEMP1]] +; CHECK-NEXT: [[TEMP1:%.*]] = call ptr @strncat(ptr noundef nonnull dereferenceable(1) [[STR1:%.*]], ptr noundef nonnull dereferenceable(1) [[STR2:%.*]], i32 5) +; CHECK-NEXT: ret ptr [[TEMP1]] ; - %temp1 = call i8* @strncat(i8* %str1, i8* %str2, i32 5) - ret i8* %temp1 + %temp1 = call ptr @strncat(ptr %str1, ptr %str2, i32 5) + ret ptr %temp1 } -define i8* @test4(i8* %str1, i8* %str2, i32 %n) null_pointer_is_valid { +define ptr @test4(ptr %str1, ptr %str2, i32 %n) null_pointer_is_valid { ; CHECK-LABEL: @test4( -; CHECK-NEXT: [[TEMP1:%.*]] = call i8* @strncat(i8* noundef [[STR1:%.*]], i8* [[STR2:%.*]], i32 [[N:%.*]]) -; CHECK-NEXT: ret i8* [[TEMP1]] +; CHECK-NEXT: [[TEMP1:%.*]] = call ptr @strncat(ptr noundef [[STR1:%.*]], ptr [[STR2:%.*]], i32 [[N:%.*]]) +; CHECK-NEXT: ret ptr [[TEMP1]] ; - %temp1 = call i8* @strncat(i8* %str1, i8* %str2, i32 %n) - ret i8* %temp1 + %temp1 = call ptr @strncat(ptr %str1, ptr %str2, i32 %n) + ret ptr %temp1 } -define i8* @test5(i8* %str, i32 %n) { +define ptr @test5(ptr %str, i32 %n) { ; CHECK-LABEL: @test5( -; CHECK-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* noundef nonnull dereferenceable(1) [[STR:%.*]]) -; CHECK-NEXT: [[ENDPTR:%.*]] = getelementptr inbounds i8, i8* [[STR]], i32 [[STRLEN]] -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(6) [[ENDPTR]], i8* noundef nonnull align 1 dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 6, i1 false) -; CHECK-NEXT: ret i8* [[STR]] +; CHECK-NEXT: [[STRLEN:%.*]] = call i32 @strlen(ptr noundef nonnull dereferenceable(1) [[STR:%.*]]) +; CHECK-NEXT: [[ENDPTR:%.*]] = getelementptr inbounds i8, ptr [[STR]], i32 [[STRLEN]] +; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr noundef nonnull align 1 dereferenceable(6) [[ENDPTR]], ptr noundef nonnull align 1 dereferenceable(6) @hello, i32 6, i1 false) +; CHECK-NEXT: ret ptr [[STR]] ; - %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - %temp1 = call i8* @strncat(i8* %str, i8* %src, i32 10) - ret i8* %temp1 + %temp1 = call ptr @strncat(ptr %str, ptr @hello, i32 10) + ret ptr %temp1 } diff --git a/llvm/test/Transforms/InstCombine/strncat-3.ll b/llvm/test/Transforms/InstCombine/strncat-3.ll --- a/llvm/test/Transforms/InstCombine/strncat-3.ll +++ b/llvm/test/Transforms/InstCombine/strncat-3.ll @@ -10,16 +10,14 @@ @empty = constant [1 x i8] c"\00" @a = common global [32 x i8] zeroinitializer, align 1 -declare i16 @strncat(i8*, i8*, i32) +declare i16 @strncat(ptr, ptr, i32) define void @test_nosimplify1() { ; CHECK-LABEL: @test_nosimplify1( -; CHECK-NEXT: [[TMP1:%.*]] = call i16 @strncat(i8* getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 13) +; CHECK-NEXT: [[TMP1:%.*]] = call i16 @strncat(ptr nonnull @a, ptr nonnull @hello, i32 13) ; CHECK-NEXT: ret void ; - %dst = getelementptr [32 x i8], [32 x i8]* @a, i32 0, i32 0 - %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - call i16 @strncat(i8* %dst, i8* %src, i32 13) + call i16 @strncat(ptr @a, ptr @hello, i32 13) ret void } diff --git a/llvm/test/Transforms/InstCombine/strncmp-2.ll b/llvm/test/Transforms/InstCombine/strncmp-2.ll --- a/llvm/test/Transforms/InstCombine/strncmp-2.ll +++ b/llvm/test/Transforms/InstCombine/strncmp-2.ll @@ -7,16 +7,14 @@ @hello = constant [6 x i8] c"hello\00" @hell = constant [5 x i8] c"hell\00" -declare i16 @strncmp(i8*, i8*, i32) +declare i16 @strncmp(ptr, ptr, i32) define i16 @test_nosimplify() { ; CHECK-LABEL: @test_nosimplify( -; CHECK-NEXT: [[TEMP1:%.*]] = call i16 @strncmp(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @hell, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 10) +; CHECK-NEXT: [[TEMP1:%.*]] = call i16 @strncmp(ptr nonnull @hell, ptr nonnull @hello, i32 10) ; CHECK-NEXT: ret i16 [[TEMP1]] ; - %str1 = getelementptr inbounds [5 x i8], [5 x i8]* @hell, i32 0, i32 0 - %str2 = getelementptr inbounds [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - %temp1 = call i16 @strncmp(i8* %str1, i8* %str2, i32 10) + %temp1 = call i16 @strncmp(ptr @hell, ptr @hello, i32 10) ret i16 %temp1 } diff --git a/llvm/test/Transforms/InstCombine/strncmp-3.ll b/llvm/test/Transforms/InstCombine/strncmp-3.ll --- a/llvm/test/Transforms/InstCombine/strncmp-3.ll +++ b/llvm/test/Transforms/InstCombine/strncmp-3.ll @@ -5,7 +5,7 @@ ; value that results in the call being incorrectly folded (as might happen ; when LLVM is compiled in ILP32 mode). -declare i32 @strncmp(i8*, i8*, i64) +declare i32 @strncmp(ptr, ptr, i64) @ax = external global [0 x i8] @bx = external global [0 x i8] @@ -18,13 +18,11 @@ define i32 @call_strncmp_ax_bx_uimax_p1() { ; CHECK-LABEL: @call_strncmp_ax_bx_uimax_p1( -; CHECK-NEXT: [[RES:%.*]] = call i32 @strncmp(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([0 x i8], [0 x i8]* @ax, i64 0, i64 0), i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([0 x i8], [0 x i8]* @bx, i64 0, i64 0), i64 4294967296) +; CHECK-NEXT: [[RES:%.*]] = call i32 @strncmp(ptr noundef nonnull @ax, ptr noundef nonnull @bx, i64 4294967296) ; CHECK-NEXT: ret i32 [[RES]] ; - %p1 = getelementptr [0 x i8], [0 x i8]* @ax, i32 0, i32 0 - %p2 = getelementptr [0 x i8], [0 x i8]* @bx, i32 0, i32 0 - %res = call i32 @strncmp(i8* %p1, i8* %p2, i64 4294967296) + %res = call i32 @strncmp(ptr @ax, ptr @bx, i64 4294967296) ret i32 %res } @@ -33,13 +31,11 @@ define i32 @call_strncmp_ax_bx_uimax_p2() { ; CHECK-LABEL: @call_strncmp_ax_bx_uimax_p2( -; CHECK-NEXT: [[RES:%.*]] = call i32 @strncmp(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([0 x i8], [0 x i8]* @ax, i64 0, i64 0), i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([0 x i8], [0 x i8]* @bx, i64 0, i64 0), i64 4294967296) +; CHECK-NEXT: [[RES:%.*]] = call i32 @strncmp(ptr noundef nonnull @ax, ptr noundef nonnull @bx, i64 4294967296) ; CHECK-NEXT: ret i32 [[RES]] ; - %p1 = getelementptr [0 x i8], [0 x i8]* @ax, i32 0, i32 0 - %p2 = getelementptr [0 x i8], [0 x i8]* @bx, i32 0, i32 0 - %res = call i32 @strncmp(i8* %p1, i8* %p2, i64 4294967296) + %res = call i32 @strncmp(ptr @ax, ptr @bx, i64 4294967296) ret i32 %res } @@ -51,9 +47,7 @@ ; CHECK-NEXT: ret i32 -1 ; - %p1 = getelementptr [5 x i8], [5 x i8]* @a12345, i32 0, i32 0 - %p2 = getelementptr [6 x i8], [6 x i8]* @a123456, i32 0, i32 0 - %res = call i32 @strncmp(i8* %p1, i8* %p2, i64 4294967297) + %res = call i32 @strncmp(ptr @a12345, ptr @a123456, i64 4294967297) ret i32 %res } @@ -65,8 +59,6 @@ ; CHECK-NEXT: ret i32 1 ; - %p1 = getelementptr [6 x i8], [6 x i8]* @a123456, i32 0, i32 0 - %p2 = getelementptr [5 x i8], [5 x i8]* @a12345, i32 0, i32 0 - %res = call i32 @strncmp(i8* %p1, i8* %p2, i64 4294967298) + %res = call i32 @strncmp(ptr @a123456, ptr @a12345, i64 4294967298) ret i32 %res } diff --git a/llvm/test/Transforms/InstCombine/strncmp-5.ll b/llvm/test/Transforms/InstCombine/strncmp-5.ll --- a/llvm/test/Transforms/InstCombine/strncmp-5.ll +++ b/llvm/test/Transforms/InstCombine/strncmp-5.ll @@ -4,7 +4,7 @@ ; Exercise folding of strncmp calls with constant arrays and nonconstant ; sizes. -declare i32 @strncmp(i8*, i8*, i64) +declare i32 @strncmp(ptr, ptr, i64) @ax = external constant [8 x i8] @a01230123 = constant [8 x i8] c"01230123" @@ -16,77 +16,74 @@ ; Exercise strncmp(A, B, N) folding of arrays with the same bytes. -define void @fold_strncmp_a_b_n(i32* %pcmp, i64 %n) { +define void @fold_strncmp_a_b_n(ptr %pcmp, i64 %n) { ; CHECK-LABEL: @fold_strncmp_a_b_n( -; CHECK-NEXT: store i32 0, i32* [[PCMP:%.*]], align 4 +; CHECK-NEXT: store i32 0, ptr [[PCMP:%.*]], align 4 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[N:%.*]], 0 ; CHECK-NEXT: [[TMP2:%.*]] = sext i1 [[TMP1]] to i32 -; CHECK-NEXT: [[S0_1:%.*]] = getelementptr i32, i32* [[PCMP]], i64 1 -; CHECK-NEXT: store i32 [[TMP2]], i32* [[S0_1]], align 4 +; CHECK-NEXT: [[S0_1:%.*]] = getelementptr i32, ptr [[PCMP]], i64 1 +; CHECK-NEXT: store i32 [[TMP2]], ptr [[S0_1]], align 4 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i64 [[N]], 0 ; CHECK-NEXT: [[TMP4:%.*]] = sext i1 [[TMP3]] to i32 -; CHECK-NEXT: [[S0_2:%.*]] = getelementptr i32, i32* [[PCMP]], i64 2 -; CHECK-NEXT: store i32 [[TMP4]], i32* [[S0_2]], align 4 +; CHECK-NEXT: [[S0_2:%.*]] = getelementptr i32, ptr [[PCMP]], i64 2 +; CHECK-NEXT: store i32 [[TMP4]], ptr [[S0_2]], align 4 ; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i64 [[N]], 0 ; CHECK-NEXT: [[TMP6:%.*]] = sext i1 [[TMP5]] to i32 -; CHECK-NEXT: [[S0_3:%.*]] = getelementptr i32, i32* [[PCMP]], i64 3 -; CHECK-NEXT: store i32 [[TMP6]], i32* [[S0_3]], align 4 -; CHECK-NEXT: [[S0_4:%.*]] = getelementptr i32, i32* [[PCMP]], i64 4 -; CHECK-NEXT: store i32 0, i32* [[S0_4]], align 4 +; CHECK-NEXT: [[S0_3:%.*]] = getelementptr i32, ptr [[PCMP]], i64 3 +; CHECK-NEXT: store i32 [[TMP6]], ptr [[S0_3]], align 4 +; CHECK-NEXT: [[S0_4:%.*]] = getelementptr i32, ptr [[PCMP]], i64 4 +; CHECK-NEXT: store i32 0, ptr [[S0_4]], align 4 ; CHECK-NEXT: [[TMP7:%.*]] = icmp ne i64 [[N]], 0 ; CHECK-NEXT: [[TMP8:%.*]] = sext i1 [[TMP7]] to i32 -; CHECK-NEXT: [[S0_5:%.*]] = getelementptr i32, i32* [[PCMP]], i64 5 -; CHECK-NEXT: store i32 [[TMP8]], i32* [[S0_5]], align 4 +; CHECK-NEXT: [[S0_5:%.*]] = getelementptr i32, ptr [[PCMP]], i64 5 +; CHECK-NEXT: store i32 [[TMP8]], ptr [[S0_5]], align 4 ; CHECK-NEXT: [[TMP9:%.*]] = icmp ne i64 [[N]], 0 ; CHECK-NEXT: [[TMP10:%.*]] = zext i1 [[TMP9]] to i32 -; CHECK-NEXT: [[S5_0:%.*]] = getelementptr i32, i32* [[PCMP]], i64 6 -; CHECK-NEXT: store i32 [[TMP10]], i32* [[S5_0]], align 4 +; CHECK-NEXT: [[S5_0:%.*]] = getelementptr i32, ptr [[PCMP]], i64 6 +; CHECK-NEXT: store i32 [[TMP10]], ptr [[S5_0]], align 4 ; CHECK-NEXT: ret void ; - %p0 = getelementptr [8 x i8], [8 x i8]* @a01230123, i64 0, i64 0 - %q0 = getelementptr [8 x i8], [8 x i8]* @b01230123, i64 0, i64 0 - %q1 = getelementptr [8 x i8], [8 x i8]* @b01230123, i64 0, i64 1 - %q2 = getelementptr [8 x i8], [8 x i8]* @b01230123, i64 0, i64 2 - %q3 = getelementptr [8 x i8], [8 x i8]* @b01230123, i64 0, i64 3 - %q4 = getelementptr [8 x i8], [8 x i8]* @b01230123, i64 0, i64 4 - %q5 = getelementptr [8 x i8], [8 x i8]* @b01230123, i64 0, i64 5 + %q1 = getelementptr [8 x i8], ptr @b01230123, i64 0, i64 1 + %q2 = getelementptr [8 x i8], ptr @b01230123, i64 0, i64 2 + %q3 = getelementptr [8 x i8], ptr @b01230123, i64 0, i64 3 + %q4 = getelementptr [8 x i8], ptr @b01230123, i64 0, i64 4 + %q5 = getelementptr [8 x i8], ptr @b01230123, i64 0, i64 5 ; Fold strncmp(a, b, n) to 0. - %c0_0 = call i32 @strncmp(i8* %p0, i8* %q0, i64 %n) - %s0_0 = getelementptr i32, i32* %pcmp, i64 0 - store i32 %c0_0, i32* %s0_0 + %c0_0 = call i32 @strncmp(ptr @a01230123, ptr @b01230123, i64 %n) + store i32 %c0_0, ptr %pcmp ; Fold strncmp(a, b + 1, n) to N != 0 ? -1 : 0. - %c0_1 = call i32 @strncmp(i8* %p0, i8* %q1, i64 %n) - %s0_1 = getelementptr i32, i32* %pcmp, i64 1 - store i32 %c0_1, i32* %s0_1 + %c0_1 = call i32 @strncmp(ptr @a01230123, ptr %q1, i64 %n) + %s0_1 = getelementptr i32, ptr %pcmp, i64 1 + store i32 %c0_1, ptr %s0_1 ; Fold strncmp(a, b + 2, n) to N != 0 ? -1 : 0. - %c0_2 = call i32 @strncmp(i8* %p0, i8* %q2, i64 %n) - %s0_2 = getelementptr i32, i32* %pcmp, i64 2 - store i32 %c0_2, i32* %s0_2 + %c0_2 = call i32 @strncmp(ptr @a01230123, ptr %q2, i64 %n) + %s0_2 = getelementptr i32, ptr %pcmp, i64 2 + store i32 %c0_2, ptr %s0_2 ; Fold strncmp(a, b + 3, n) to N != 0 ? -1 : 0. - %c0_3 = call i32 @strncmp(i8* %p0, i8* %q3, i64 %n) - %s0_3 = getelementptr i32, i32* %pcmp, i64 3 - store i32 %c0_3, i32* %s0_3 + %c0_3 = call i32 @strncmp(ptr @a01230123, ptr %q3, i64 %n) + %s0_3 = getelementptr i32, ptr %pcmp, i64 3 + store i32 %c0_3, ptr %s0_3 ; Fold strncmp(a, b + 4, n) to 0. - %c0_4 = call i32 @strncmp(i8* %p0, i8* %q4, i64 %n) - %s0_4 = getelementptr i32, i32* %pcmp, i64 4 - store i32 %c0_4, i32* %s0_4 + %c0_4 = call i32 @strncmp(ptr @a01230123, ptr %q4, i64 %n) + %s0_4 = getelementptr i32, ptr %pcmp, i64 4 + store i32 %c0_4, ptr %s0_4 ; Fold strncmp(a, b + 5, n) to N != 0 ? -1 : 0. - %c0_5 = call i32 @strncmp(i8* %p0, i8* %q5, i64 %n) - %s0_5 = getelementptr i32, i32* %pcmp, i64 5 - store i32 %c0_5, i32* %s0_5 + %c0_5 = call i32 @strncmp(ptr @a01230123, ptr %q5, i64 %n) + %s0_5 = getelementptr i32, ptr %pcmp, i64 5 + store i32 %c0_5, ptr %s0_5 ; Fold strncmp(b + 5, a, n) to N != 0 ? +1 : 0. - %c5_0 = call i32 @strncmp(i8* %q5, i8* %p0, i64 %n) - %s5_0 = getelementptr i32, i32* %pcmp, i64 6 - store i32 %c5_0, i32* %s5_0 + %c5_0 = call i32 @strncmp(ptr %q5, ptr @a01230123, i64 %n) + %s5_0 = getelementptr i32, ptr %pcmp, i64 6 + store i32 %c5_0, ptr %s5_0 ret void } @@ -94,20 +91,17 @@ ; Vefify that a strncmp() call involving a constant array with unknown ; contents is not folded. -define void @call_strncmp_a_ax_n(i32* %pcmp, i64 %n) { +define void @call_strncmp_a_ax_n(ptr %pcmp, i64 %n) { ; CHECK-LABEL: @call_strncmp_a_ax_n( -; CHECK-NEXT: [[C0_0:%.*]] = call i32 @strncmp(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @a01230123, i64 0, i64 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @ax, i64 0, i64 0), i64 [[N:%.*]]) -; CHECK-NEXT: store i32 [[C0_0]], i32* [[PCMP:%.*]], align 4 +; CHECK-NEXT: [[C0_0:%.*]] = call i32 @strncmp(ptr nonnull @a01230123, ptr nonnull @ax, i64 [[N:%.*]]) +; CHECK-NEXT: store i32 [[C0_0]], ptr [[PCMP:%.*]], align 4 ; CHECK-NEXT: ret void ; - %p0 = getelementptr [8 x i8], [8 x i8]* @a01230123, i64 0, i64 0 - %q0 = getelementptr [8 x i8], [8 x i8]* @ax, i64 0, i64 0 ; Do not fold strncmp(a, ax, n). - %c0_0 = call i32 @strncmp(i8* %p0, i8* %q0, i64 %n) - %s0_0 = getelementptr i32, i32* %pcmp, i64 0 - store i32 %c0_0, i32* %s0_0 + %c0_0 = call i32 @strncmp(ptr @a01230123, ptr @ax, i64 %n) + store i32 %c0_0, ptr %pcmp ret void } @@ -116,72 +110,69 @@ ; Exercise strncmp(A, C, N) folding of arrays with the same leading bytes ; but a difference in the trailing byte. -define void @fold_strncmp_a_c_n(i32* %pcmp, i64 %n) { +define void @fold_strncmp_a_c_n(ptr %pcmp, i64 %n) { ; CHECK-LABEL: @fold_strncmp_a_c_n( ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i64 [[N:%.*]], 7 ; CHECK-NEXT: [[TMP2:%.*]] = sext i1 [[TMP1]] to i32 -; CHECK-NEXT: store i32 [[TMP2]], i32* [[PCMP:%.*]], align 4 +; CHECK-NEXT: store i32 [[TMP2]], ptr [[PCMP:%.*]], align 4 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i64 [[N]], 0 ; CHECK-NEXT: [[TMP4:%.*]] = sext i1 [[TMP3]] to i32 -; CHECK-NEXT: [[S0_1:%.*]] = getelementptr i32, i32* [[PCMP]], i64 1 -; CHECK-NEXT: store i32 [[TMP4]], i32* [[S0_1]], align 4 +; CHECK-NEXT: [[S0_1:%.*]] = getelementptr i32, ptr [[PCMP]], i64 1 +; CHECK-NEXT: store i32 [[TMP4]], ptr [[S0_1]], align 4 ; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i64 [[N]], 0 ; CHECK-NEXT: [[TMP6:%.*]] = sext i1 [[TMP5]] to i32 -; CHECK-NEXT: [[S0_2:%.*]] = getelementptr i32, i32* [[PCMP]], i64 2 -; CHECK-NEXT: store i32 [[TMP6]], i32* [[S0_2]], align 4 +; CHECK-NEXT: [[S0_2:%.*]] = getelementptr i32, ptr [[PCMP]], i64 2 +; CHECK-NEXT: store i32 [[TMP6]], ptr [[S0_2]], align 4 ; CHECK-NEXT: [[TMP7:%.*]] = icmp ne i64 [[N]], 0 ; CHECK-NEXT: [[TMP8:%.*]] = sext i1 [[TMP7]] to i32 -; CHECK-NEXT: [[S0_3:%.*]] = getelementptr i32, i32* [[PCMP]], i64 3 -; CHECK-NEXT: store i32 [[TMP8]], i32* [[S0_3]], align 4 +; CHECK-NEXT: [[S0_3:%.*]] = getelementptr i32, ptr [[PCMP]], i64 3 +; CHECK-NEXT: store i32 [[TMP8]], ptr [[S0_3]], align 4 ; CHECK-NEXT: [[TMP9:%.*]] = icmp ugt i64 [[N]], 3 ; CHECK-NEXT: [[TMP10:%.*]] = sext i1 [[TMP9]] to i32 -; CHECK-NEXT: [[S0_4:%.*]] = getelementptr i32, i32* [[PCMP]], i64 4 -; CHECK-NEXT: store i32 [[TMP10]], i32* [[S0_4]], align 4 +; CHECK-NEXT: [[S0_4:%.*]] = getelementptr i32, ptr [[PCMP]], i64 4 +; CHECK-NEXT: store i32 [[TMP10]], ptr [[S0_4]], align 4 ; CHECK-NEXT: [[TMP11:%.*]] = icmp ugt i64 [[N]], 3 ; CHECK-NEXT: [[TMP12:%.*]] = sext i1 [[TMP11]] to i32 -; CHECK-NEXT: [[S0_5:%.*]] = getelementptr i32, i32* [[PCMP]], i64 5 -; CHECK-NEXT: store i32 [[TMP12]], i32* [[S0_5]], align 4 +; CHECK-NEXT: [[S0_5:%.*]] = getelementptr i32, ptr [[PCMP]], i64 5 +; CHECK-NEXT: store i32 [[TMP12]], ptr [[S0_5]], align 4 ; CHECK-NEXT: ret void ; - %p0 = getelementptr [8 x i8], [8 x i8]* @a01230123, i64 0, i64 0 - %q0 = getelementptr [8 x i8], [8 x i8]* @c01230129, i64 0, i64 0 - %q1 = getelementptr [8 x i8], [8 x i8]* @c01230129, i64 0, i64 1 - %q2 = getelementptr [8 x i8], [8 x i8]* @c01230129, i64 0, i64 2 - %q3 = getelementptr [8 x i8], [8 x i8]* @c01230129, i64 0, i64 3 - %q4 = getelementptr [8 x i8], [8 x i8]* @c01230129, i64 0, i64 4 - %q5 = getelementptr [8 x i8], [8 x i8]* @c01230129, i64 0, i64 5 + %q1 = getelementptr [8 x i8], ptr @c01230129, i64 0, i64 1 + %q2 = getelementptr [8 x i8], ptr @c01230129, i64 0, i64 2 + %q3 = getelementptr [8 x i8], ptr @c01230129, i64 0, i64 3 + %q4 = getelementptr [8 x i8], ptr @c01230129, i64 0, i64 4 + %q5 = getelementptr [8 x i8], ptr @c01230129, i64 0, i64 5 ; Fold strncmp(a, c, n) to N > 7 ? -1 : 0. - %c0_0 = call i32 @strncmp(i8* %p0, i8* %q0, i64 %n) - %s0_0 = getelementptr i32, i32* %pcmp, i64 0 - store i32 %c0_0, i32* %s0_0 + %c0_0 = call i32 @strncmp(ptr @a01230123, ptr @c01230129, i64 %n) + store i32 %c0_0, ptr %pcmp ; Fold strncmp(a, c + 1, n) to N != 0 ? -1 : 0. - %c0_1 = call i32 @strncmp(i8* %p0, i8* %q1, i64 %n) - %s0_1 = getelementptr i32, i32* %pcmp, i64 1 - store i32 %c0_1, i32* %s0_1 + %c0_1 = call i32 @strncmp(ptr @a01230123, ptr %q1, i64 %n) + %s0_1 = getelementptr i32, ptr %pcmp, i64 1 + store i32 %c0_1, ptr %s0_1 ; Fold strncmp(a, c + 2, n) to N != 0 ? -1 : 0. - %c0_2 = call i32 @strncmp(i8* %p0, i8* %q2, i64 %n) - %s0_2 = getelementptr i32, i32* %pcmp, i64 2 - store i32 %c0_2, i32* %s0_2 + %c0_2 = call i32 @strncmp(ptr @a01230123, ptr %q2, i64 %n) + %s0_2 = getelementptr i32, ptr %pcmp, i64 2 + store i32 %c0_2, ptr %s0_2 ; Fold strncmp(a, c + 3, n) to N != 0 ? -1 : 0. - %c0_3 = call i32 @strncmp(i8* %p0, i8* %q3, i64 %n) - %s0_3 = getelementptr i32, i32* %pcmp, i64 3 - store i32 %c0_3, i32* %s0_3 + %c0_3 = call i32 @strncmp(ptr @a01230123, ptr %q3, i64 %n) + %s0_3 = getelementptr i32, ptr %pcmp, i64 3 + store i32 %c0_3, ptr %s0_3 ; Fold strncmp(a, c + 4, n) to N > 3 ? -1 : 0. - %c0_4 = call i32 @strncmp(i8* %p0, i8* %q4, i64 %n) - %s0_4 = getelementptr i32, i32* %pcmp, i64 4 - store i32 %c0_4, i32* %s0_4 + %c0_4 = call i32 @strncmp(ptr @a01230123, ptr %q4, i64 %n) + %s0_4 = getelementptr i32, ptr %pcmp, i64 4 + store i32 %c0_4, ptr %s0_4 ; Fold strncmp(a, c + 5, n) to N != 0 ? -1 : 0. - %c0_5 = call i32 @strncmp(i8* %p0, i8* %q4, i64 %n) - %s0_5 = getelementptr i32, i32* %pcmp, i64 5 - store i32 %c0_5, i32* %s0_5 + %c0_5 = call i32 @strncmp(ptr @a01230123, ptr %q4, i64 %n) + %s0_5 = getelementptr i32, ptr %pcmp, i64 5 + store i32 %c0_5, ptr %s0_5 ret void } @@ -190,99 +181,96 @@ ; Exercise strncmp(A, D, N) folding of arrays of different sizes and ; a difference in the leading byte. -define void @fold_strncmp_a_d_n(i32* %pcmp, i64 %n) { +define void @fold_strncmp_a_d_n(ptr %pcmp, i64 %n) { ; CHECK-LABEL: @fold_strncmp_a_d_n( ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[N:%.*]], 0 ; CHECK-NEXT: [[TMP2:%.*]] = sext i1 [[TMP1]] to i32 -; CHECK-NEXT: store i32 [[TMP2]], i32* [[PCMP:%.*]], align 4 +; CHECK-NEXT: store i32 [[TMP2]], ptr [[PCMP:%.*]], align 4 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i64 [[N]], 0 ; CHECK-NEXT: [[TMP4:%.*]] = sext i1 [[TMP3]] to i32 -; CHECK-NEXT: [[S0_1:%.*]] = getelementptr i32, i32* [[PCMP]], i64 1 -; CHECK-NEXT: store i32 [[TMP4]], i32* [[S0_1]], align 4 +; CHECK-NEXT: [[S0_1:%.*]] = getelementptr i32, ptr [[PCMP]], i64 1 +; CHECK-NEXT: store i32 [[TMP4]], ptr [[S0_1]], align 4 ; CHECK-NEXT: [[TMP5:%.*]] = icmp ugt i64 [[N]], 3 ; CHECK-NEXT: [[TMP6:%.*]] = zext i1 [[TMP5]] to i32 -; CHECK-NEXT: [[S1_1:%.*]] = getelementptr i32, i32* [[PCMP]], i64 2 -; CHECK-NEXT: store i32 [[TMP6]], i32* [[S1_1]], align 4 +; CHECK-NEXT: [[S1_1:%.*]] = getelementptr i32, ptr [[PCMP]], i64 2 +; CHECK-NEXT: store i32 [[TMP6]], ptr [[S1_1]], align 4 ; CHECK-NEXT: [[TMP7:%.*]] = icmp ugt i64 [[N]], 2 ; CHECK-NEXT: [[TMP8:%.*]] = zext i1 [[TMP7]] to i32 -; CHECK-NEXT: [[S2_2:%.*]] = getelementptr i32, i32* [[PCMP]], i64 3 -; CHECK-NEXT: store i32 [[TMP8]], i32* [[S2_2]], align 4 +; CHECK-NEXT: [[S2_2:%.*]] = getelementptr i32, ptr [[PCMP]], i64 3 +; CHECK-NEXT: store i32 [[TMP8]], ptr [[S2_2]], align 4 ; CHECK-NEXT: [[TMP9:%.*]] = icmp ne i64 [[N]], 0 ; CHECK-NEXT: [[TMP10:%.*]] = zext i1 [[TMP9]] to i32 -; CHECK-NEXT: [[S4_4:%.*]] = getelementptr i32, i32* [[PCMP]], i64 4 -; CHECK-NEXT: store i32 [[TMP10]], i32* [[S4_4]], align 4 +; CHECK-NEXT: [[S4_4:%.*]] = getelementptr i32, ptr [[PCMP]], i64 4 +; CHECK-NEXT: store i32 [[TMP10]], ptr [[S4_4]], align 4 ; CHECK-NEXT: [[TMP11:%.*]] = icmp ne i64 [[N]], 0 ; CHECK-NEXT: [[TMP12:%.*]] = sext i1 [[TMP11]] to i32 -; CHECK-NEXT: [[S4_4_2:%.*]] = getelementptr i32, i32* [[PCMP]], i64 5 -; CHECK-NEXT: store i32 [[TMP12]], i32* [[S4_4_2]], align 4 -; CHECK-NEXT: [[S5_5:%.*]] = getelementptr i32, i32* [[PCMP]], i64 6 -; CHECK-NEXT: store i32 0, i32* [[S5_5]], align 4 -; CHECK-NEXT: [[S6_6:%.*]] = getelementptr i32, i32* [[PCMP]], i64 7 -; CHECK-NEXT: store i32 0, i32* [[S6_6]], align 4 +; CHECK-NEXT: [[S4_4_2:%.*]] = getelementptr i32, ptr [[PCMP]], i64 5 +; CHECK-NEXT: store i32 [[TMP12]], ptr [[S4_4_2]], align 4 +; CHECK-NEXT: [[S5_5:%.*]] = getelementptr i32, ptr [[PCMP]], i64 6 +; CHECK-NEXT: store i32 0, ptr [[S5_5]], align 4 +; CHECK-NEXT: [[S6_6:%.*]] = getelementptr i32, ptr [[PCMP]], i64 7 +; CHECK-NEXT: store i32 0, ptr [[S6_6]], align 4 ; CHECK-NEXT: ret void ; - %p0 = getelementptr [8 x i8], [8 x i8]* @a01230123, i64 0, i64 0 - %p1 = getelementptr [8 x i8], [8 x i8]* @a01230123, i64 0, i64 1 - %p2 = getelementptr [8 x i8], [8 x i8]* @a01230123, i64 0, i64 2 - %p3 = getelementptr [8 x i8], [8 x i8]* @a01230123, i64 0, i64 3 - %p4 = getelementptr [8 x i8], [8 x i8]* @a01230123, i64 0, i64 4 - %p5 = getelementptr [8 x i8], [8 x i8]* @a01230123, i64 0, i64 5 - %p6 = getelementptr [8 x i8], [8 x i8]* @a01230123, i64 0, i64 6 - - %q0 = getelementptr [7 x i8], [7 x i8]* @d9123_12, i64 0, i64 0 - %q1 = getelementptr [7 x i8], [7 x i8]* @d9123_12, i64 0, i64 1 - %q2 = getelementptr [7 x i8], [7 x i8]* @d9123_12, i64 0, i64 2 - %q3 = getelementptr [7 x i8], [7 x i8]* @d9123_12, i64 0, i64 3 - %q4 = getelementptr [7 x i8], [7 x i8]* @d9123_12, i64 0, i64 4 - %q5 = getelementptr [7 x i8], [7 x i8]* @d9123_12, i64 0, i64 5 - %q6 = getelementptr [7 x i8], [7 x i8]* @d9123_12, i64 0, i64 6 + %p1 = getelementptr [8 x i8], ptr @a01230123, i64 0, i64 1 + %p2 = getelementptr [8 x i8], ptr @a01230123, i64 0, i64 2 + %p3 = getelementptr [8 x i8], ptr @a01230123, i64 0, i64 3 + %p4 = getelementptr [8 x i8], ptr @a01230123, i64 0, i64 4 + %p5 = getelementptr [8 x i8], ptr @a01230123, i64 0, i64 5 + %p6 = getelementptr [8 x i8], ptr @a01230123, i64 0, i64 6 + + %q1 = getelementptr [7 x i8], ptr @d9123_12, i64 0, i64 1 + %q2 = getelementptr [7 x i8], ptr @d9123_12, i64 0, i64 2 + %q3 = getelementptr [7 x i8], ptr @d9123_12, i64 0, i64 3 + %q4 = getelementptr [7 x i8], ptr @d9123_12, i64 0, i64 4 + %q5 = getelementptr [7 x i8], ptr @d9123_12, i64 0, i64 5 + %q6 = getelementptr [7 x i8], ptr @d9123_12, i64 0, i64 6 ; Fold strncmp(a, d, n) to N != 0 ? -1 : 0. - %c0_0 = call i32 @strncmp(i8* %p0, i8* %q0, i64 %n) - %s0_0 = getelementptr i32, i32* %pcmp, i64 0 - store i32 %c0_0, i32* %s0_0 + %c0_0 = call i32 @strncmp(ptr @a01230123, ptr @d9123_12, i64 %n) + store i32 %c0_0, ptr %pcmp ; Fold strncmp(a, d + 1, n) to N != 0 ? -1 : 0. - %c0_1 = call i32 @strncmp(i8* %p0, i8* %q1, i64 %n) - %s0_1 = getelementptr i32, i32* %pcmp, i64 1 - store i32 %c0_1, i32* %s0_1 + %c0_1 = call i32 @strncmp(ptr @a01230123, ptr %q1, i64 %n) + %s0_1 = getelementptr i32, ptr %pcmp, i64 1 + store i32 %c0_1, ptr %s0_1 ; Fold strncmp(a + 1, d + 1, n) N > 3 ? +1 : 0. - %c1_1 = call i32 @strncmp(i8* %p1, i8* %q1, i64 %n) - %s1_1 = getelementptr i32, i32* %pcmp, i64 2 - store i32 %c1_1, i32* %s1_1 + %c1_1 = call i32 @strncmp(ptr %p1, ptr %q1, i64 %n) + %s1_1 = getelementptr i32, ptr %pcmp, i64 2 + store i32 %c1_1, ptr %s1_1 ; Fold strncmp(a + 2, d + 2, n) N > 2 ? +1 : 0. - %c2_2 = call i32 @strncmp(i8* %p2, i8* %q2, i64 %n) - %s2_2 = getelementptr i32, i32* %pcmp, i64 3 - store i32 %c2_2, i32* %s2_2 + %c2_2 = call i32 @strncmp(ptr %p2, ptr %q2, i64 %n) + %s2_2 = getelementptr i32, ptr %pcmp, i64 3 + store i32 %c2_2, ptr %s2_2 ; Fold strncmp(a + 3, d + 3, n) N > 1 ? +1 : 0. - %c3_3 = call i32 @strncmp(i8* %p3, i8* %q3, i64 %n) - %s3_3 = getelementptr i32, i32* %pcmp, i64 4 - store i32 %c3_3, i32* %s3_3 + %c3_3 = call i32 @strncmp(ptr %p3, ptr %q3, i64 %n) + %s3_3 = getelementptr i32, ptr %pcmp, i64 4 + store i32 %c3_3, ptr %s3_3 ; Fold strncmp(a + 4, d + 4, n) N != 0 ? +1 : 0. - %c4_4 = call i32 @strncmp(i8* %p4, i8* %q4, i64 %n) - %s4_4 = getelementptr i32, i32* %pcmp, i64 4 - store i32 %c4_4, i32* %s4_4 + %c4_4 = call i32 @strncmp(ptr %p4, ptr %q4, i64 %n) + %s4_4 = getelementptr i32, ptr %pcmp, i64 4 + store i32 %c4_4, ptr %s4_4 ; Fold strncmp(d + 4, a + 4, n) N != 0 ? -1 : 0 (same as above but ; with the array arguments reversed). - %c4_4_2 = call i32 @strncmp(i8* %q4, i8* %p4, i64 %n) - %s4_4_2 = getelementptr i32, i32* %pcmp, i64 5 - store i32 %c4_4_2, i32* %s4_4_2 + %c4_4_2 = call i32 @strncmp(ptr %q4, ptr %p4, i64 %n) + %s4_4_2 = getelementptr i32, ptr %pcmp, i64 5 + store i32 %c4_4_2, ptr %s4_4_2 ; Fold strncmp(a + 5, d + 5, n) to 0. - %c5_5 = call i32 @strncmp(i8* %p5, i8* %q5, i64 %n) - %s5_5 = getelementptr i32, i32* %pcmp, i64 6 - store i32 %c5_5, i32* %s5_5 + %c5_5 = call i32 @strncmp(ptr %p5, ptr %q5, i64 %n) + %s5_5 = getelementptr i32, ptr %pcmp, i64 6 + store i32 %c5_5, ptr %s5_5 ; Fold strncmp(a + 6, d + 6, n) to 0. - %c6_6 = call i32 @strncmp(i8* %p6, i8* %q6, i64 %n) - %s6_6 = getelementptr i32, i32* %pcmp, i64 7 - store i32 %c6_6, i32* %s6_6 + %c6_6 = call i32 @strncmp(ptr %p6, ptr %q6, i64 %n) + %s6_6 = getelementptr i32, ptr %pcmp, i64 7 + store i32 %c6_6, ptr %s6_6 ret void } @@ -291,19 +279,16 @@ ; Exercise strncmp(A, D, N) folding of arrays with the same bytes and ; a nonzero size. -define void @fold_strncmp_a_d_nz(i32* %pcmp, i64 %n) { +define void @fold_strncmp_a_d_nz(ptr %pcmp, i64 %n) { ; CHECK-LABEL: @fold_strncmp_a_d_nz( -; CHECK-NEXT: store i32 -1, i32* [[PCMP:%.*]], align 4 +; CHECK-NEXT: store i32 -1, ptr [[PCMP:%.*]], align 4 ; CHECK-NEXT: ret void ; - %p0 = getelementptr [8 x i8], [8 x i8]* @a01230123, i64 0, i64 0 - %q0 = getelementptr [7 x i8], [7 x i8]* @d9123_12, i64 0, i64 0 %nz = or i64 %n, 1 - %c0_0 = call i32 @strncmp(i8* %p0, i8* %q0, i64 %nz) - %s0_0 = getelementptr i32, i32* %pcmp, i64 0 - store i32 %c0_0, i32* %s0_0 + %c0_0 = call i32 @strncmp(ptr @a01230123, ptr @d9123_12, i64 %nz) + store i32 %c0_0, ptr %pcmp ret void } @@ -311,47 +296,44 @@ ; Exercise strncmp(D, E, N) folding of equal strings but unequal arrays. -define void @fold_strncmp_d_e_n(i32* %pcmp, i64 %n) { +define void @fold_strncmp_d_e_n(ptr %pcmp, i64 %n) { ; CHECK-LABEL: @fold_strncmp_d_e_n( -; CHECK-NEXT: store i32 0, i32* [[PCMP:%.*]], align 4 +; CHECK-NEXT: store i32 0, ptr [[PCMP:%.*]], align 4 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[N:%.*]], 0 ; CHECK-NEXT: [[TMP2:%.*]] = zext i1 [[TMP1]] to i32 -; CHECK-NEXT: [[S0_1:%.*]] = getelementptr i32, i32* [[PCMP]], i64 1 -; CHECK-NEXT: store i32 [[TMP2]], i32* [[S0_1]], align 4 +; CHECK-NEXT: [[S0_1:%.*]] = getelementptr i32, ptr [[PCMP]], i64 1 +; CHECK-NEXT: store i32 [[TMP2]], ptr [[S0_1]], align 4 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i64 [[N]], 0 ; CHECK-NEXT: [[TMP4:%.*]] = sext i1 [[TMP3]] to i32 -; CHECK-NEXT: [[S1_0:%.*]] = getelementptr i32, i32* [[PCMP]], i64 2 -; CHECK-NEXT: store i32 [[TMP4]], i32* [[S1_0]], align 4 -; CHECK-NEXT: [[S1_1:%.*]] = getelementptr i32, i32* [[PCMP]], i64 3 -; CHECK-NEXT: store i32 0, i32* [[S1_1]], align 4 +; CHECK-NEXT: [[S1_0:%.*]] = getelementptr i32, ptr [[PCMP]], i64 2 +; CHECK-NEXT: store i32 [[TMP4]], ptr [[S1_0]], align 4 +; CHECK-NEXT: [[S1_1:%.*]] = getelementptr i32, ptr [[PCMP]], i64 3 +; CHECK-NEXT: store i32 0, ptr [[S1_1]], align 4 ; CHECK-NEXT: ret void ; - %p0 = getelementptr [7 x i8], [7 x i8]* @d9123_12, i64 0, i64 0 - %p1 = getelementptr [7 x i8], [7 x i8]* @d9123_12, i64 0, i64 1 + %p1 = getelementptr [7 x i8], ptr @d9123_12, i64 0, i64 1 - %q0 = getelementptr [7 x i8], [7 x i8]* @e9123_34, i64 0, i64 0 - %q1 = getelementptr [7 x i8], [7 x i8]* @e9123_34, i64 0, i64 1 + %q1 = getelementptr [7 x i8], ptr @e9123_34, i64 0, i64 1 ; Fold to 0. - %c0_0 = call i32 @strncmp(i8* %p0, i8* %q0, i64 %n) - %s0_0 = getelementptr i32, i32* %pcmp, i64 0 - store i32 %c0_0, i32* %s0_0 + %c0_0 = call i32 @strncmp(ptr @d9123_12, ptr @e9123_34, i64 %n) + store i32 %c0_0, ptr %pcmp ; Fold to N ? +1 : 0. - %c0_1 = call i32 @strncmp(i8* %p0, i8* %q1, i64 %n) - %s0_1 = getelementptr i32, i32* %pcmp, i64 1 - store i32 %c0_1, i32* %s0_1 + %c0_1 = call i32 @strncmp(ptr @d9123_12, ptr %q1, i64 %n) + %s0_1 = getelementptr i32, ptr %pcmp, i64 1 + store i32 %c0_1, ptr %s0_1 ; Fold to N ? -1 : 0. - %c1_0 = call i32 @strncmp(i8* %p1, i8* %q0, i64 %n) - %s1_0 = getelementptr i32, i32* %pcmp, i64 2 - store i32 %c1_0, i32* %s1_0 + %c1_0 = call i32 @strncmp(ptr %p1, ptr @e9123_34, i64 %n) + %s1_0 = getelementptr i32, ptr %pcmp, i64 2 + store i32 %c1_0, ptr %s1_0 ; Fold to 0. - %c1_1 = call i32 @strncmp(i8* %p1, i8* %q1, i64 %n) - %s1_1 = getelementptr i32, i32* %pcmp, i64 3 - store i32 %c1_1, i32* %s1_1 + %c1_1 = call i32 @strncmp(ptr %p1, ptr %q1, i64 %n) + %s1_1 = getelementptr i32, ptr %pcmp, i64 3 + store i32 %c1_1, ptr %s1_1 ret void } diff --git a/llvm/test/Transforms/InstCombine/strncpy-1.ll b/llvm/test/Transforms/InstCombine/strncpy-1.ll --- a/llvm/test/Transforms/InstCombine/strncpy-1.ll +++ b/llvm/test/Transforms/InstCombine/strncpy-1.ll @@ -11,36 +11,31 @@ @a = common global [32 x i8] zeroinitializer, align 1 @b = common global [32 x i8] zeroinitializer, align 1 -declare i8* @strncpy(i8*, i8*, i32) -declare i32 @puts(i8*) +declare ptr @strncpy(ptr, ptr, i32) +declare i32 @puts(ptr) ; Check a bunch of strncpy invocations together. define i32 @test_simplify1() { ; CHECK-LABEL: @test_simplify1( ; CHECK-NEXT: [[TARGET:%.*]] = alloca [1024 x i8], align 1 -; CHECK-NEXT: [[ARG1:%.*]] = getelementptr inbounds [1024 x i8], [1024 x i8]* [[TARGET]], i32 0, i32 0 -; CHECK-NEXT: store i8 0, i8* [[ARG1]], align 1 -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(6) [[ARG1]], i8* noundef nonnull align 1 dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 6, i1 false) -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(42) [[ARG1]], i8 0, i32 42, i1 false) -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(42) [[ARG1]], i8 0, i32 42, i1 false) -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @puts(i8* noundef nonnull [[ARG1]]) +; CHECK-NEXT: store i8 0, ptr [[TARGET]], align 1 +; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr noundef nonnull align 1 dereferenceable(6) [[TARGET]], ptr noundef nonnull align 1 dereferenceable(6) @hello, i32 6, i1 false) +; CHECK-NEXT: call void @llvm.memset.p0.i32(ptr noundef nonnull align 1 dereferenceable(42) [[TARGET]], i8 0, i32 42, i1 false) +; CHECK-NEXT: call void @llvm.memset.p0.i32(ptr noundef nonnull align 1 dereferenceable(42) [[TARGET]], i8 0, i32 42, i1 false) +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @puts(ptr noundef nonnull [[TARGET]]) ; CHECK-NEXT: ret i32 0 ; %target = alloca [1024 x i8] - %arg1 = getelementptr [1024 x i8], [1024 x i8]* %target, i32 0, i32 0 - store i8 0, i8* %arg1 + store i8 0, ptr %target - %arg2 = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - %rslt1 = call i8* @strncpy(i8* %arg1, i8* %arg2, i32 6) + %rslt1 = call ptr @strncpy(ptr %target, ptr @hello, i32 6) - %arg3 = getelementptr [1 x i8], [1 x i8]* @null, i32 0, i32 0 - %rslt2 = call i8* @strncpy(i8* %rslt1, i8* %arg3, i32 42) + %rslt2 = call ptr @strncpy(ptr %rslt1, ptr @null, i32 42) - %arg4 = getelementptr [7 x i8], [7 x i8]* @null_hello, i32 0, i32 0 - %rslt3 = call i8* @strncpy(i8* %rslt2, i8* %arg4, i32 42) + %rslt3 = call ptr @strncpy(ptr %rslt2, ptr @null_hello, i32 42) - call i32 @puts( i8* %rslt3 ) + call i32 @puts( ptr %rslt3 ) ret i32 0 } @@ -48,66 +43,58 @@ define void @test_simplify2() { ; CHECK-LABEL: @test_simplify2( -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(32) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0), i8 0, i32 32, i1 false) +; CHECK-NEXT: call void @llvm.memset.p0.i32(ptr noundef nonnull align 1 dereferenceable(32) @a, i8 0, i32 32, i1 false) ; CHECK-NEXT: ret void ; - %dst = getelementptr [32 x i8], [32 x i8]* @a, i32 0, i32 0 - %src = getelementptr [1 x i8], [1 x i8]* @null, i32 0, i32 0 - call i8* @strncpy(i8* %dst, i8* %src, i32 32) + call ptr @strncpy(ptr @a, ptr @null, i32 32) ret void } ; Check strncpy(x, y, 0) -> x. -define i8* @test_simplify3() { +define ptr @test_simplify3() { ; CHECK-LABEL: @test_simplify3( -; CHECK-NEXT: ret i8* getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0) +; CHECK-NEXT: ret ptr @a ; - %dst = getelementptr [32 x i8], [32 x i8]* @a, i32 0, i32 0 - %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - %ret = call i8* @strncpy(i8* %dst, i8* %src, i32 0) - ret i8* %ret + %ret = call ptr @strncpy(ptr @a, ptr @hello, i32 0) + ret ptr %ret } ; Check strncpy(x, s, c) -> memcpy(x, s, c, 1) [s and c are constant]. define void @test_simplify4() { ; CHECK-LABEL: @test_simplify4( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(6) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0), i8* noundef nonnull align 1 dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 6, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr noundef nonnull align 1 dereferenceable(6) @a, ptr noundef nonnull align 1 dereferenceable(6) @hello, i32 6, i1 false) ; CHECK-NEXT: ret void ; - %dst = getelementptr [32 x i8], [32 x i8]* @a, i32 0, i32 0 - %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - call i8* @strncpy(i8* %dst, i8* %src, i32 6) + call ptr @strncpy(ptr @a, ptr @hello, i32 6) ret void } -define void @test_simplify5(i8* %dst) { +define void @test_simplify5(ptr %dst) { ; CHECK-LABEL: @test_simplify5( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(32) [[DST:%.*]], i8* noundef nonnull align 1 dereferenceable(32) getelementptr inbounds ([33 x i8], [33 x i8]* @str, i32 0, i32 0), i32 32, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr noundef nonnull align 1 dereferenceable(32) [[DST:%.*]], ptr noundef nonnull align 1 dereferenceable(32) @str, i32 32, i1 false) ; CHECK-NEXT: ret void ; - %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - call i8* @strncpy(i8* dereferenceable(8) %dst, i8* %src, i32 32) + call ptr @strncpy(ptr dereferenceable(8) %dst, ptr @hello, i32 32) ret void } -define void @test_simplify6(i8* %dst) { +define void @test_simplify6(ptr %dst) { ; CHECK-LABEL: @test_simplify6( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(80) [[DST:%.*]], i8* noundef nonnull align 1 dereferenceable(32) getelementptr inbounds ([33 x i8], [33 x i8]* @str.1, i32 0, i32 0), i32 32, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr noundef nonnull align 1 dereferenceable(80) [[DST:%.*]], ptr noundef nonnull align 1 dereferenceable(32) @str.1, i32 32, i1 false) ; CHECK-NEXT: ret void ; - %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - call i8* @strncpy(i8* dereferenceable(80) %dst, i8* %src, i32 32) + call ptr @strncpy(ptr dereferenceable(80) %dst, ptr @hello, i32 32) ret void } -define void @test_simplify7(i8* %dst, i32 %n) { +define void @test_simplify7(ptr %dst, i32 %n) { ; CHECK-LABEL: @test_simplify7( -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* align 1 dereferenceable(80) [[DST:%.*]], i8 0, i32 [[N:%.*]], i1 false) +; CHECK-NEXT: call void @llvm.memset.p0.i32(ptr align 1 dereferenceable(80) [[DST:%.*]], i8 0, i32 [[N:%.*]], i1 false) ; CHECK-NEXT: ret void ; ; Unless N is known to be nonzero, strncpy(D, "", N) need not access any @@ -115,110 +102,98 @@ ; TODO: The argument, already annotated dereferenceable, should be ; annotated noundef and nonnull by the transformation. See ; https://reviews.llvm.org/D124633. -; - %src = getelementptr [1 x i8], [1 x i8]* @null, i32 0, i32 0 - call i8* @strncpy(i8* dereferenceable(80) %dst, i8* %src, i32 %n) + call ptr @strncpy(ptr dereferenceable(80) %dst, ptr @null, i32 %n) ret void } -define i8* @test1(i8* %dst, i8* %src, i32 %n) { +define ptr @test1(ptr %dst, ptr %src, i32 %n) { ; CHECK-LABEL: @test1( -; CHECK-NEXT: [[RET:%.*]] = call i8* @strncpy(i8* nonnull [[DST:%.*]], i8* nonnull [[SRC:%.*]], i32 [[N:%.*]]) -; CHECK-NEXT: ret i8* [[RET]] +; CHECK-NEXT: [[RET:%.*]] = call ptr @strncpy(ptr nonnull [[DST:%.*]], ptr nonnull [[SRC:%.*]], i32 [[N:%.*]]) +; CHECK-NEXT: ret ptr [[RET]] ; ; Unless N is known to be nonzero, strncpy(D, S, N) need not access any ; bytes in either D or S. Verify that the call isn't annotated with ; the dereferenceable attribute. ; TODO: Both arguments should be annotated noundef in addition to nonnull. ; See https://reviews.llvm.org/D124633. -; - %ret = call i8* @strncpy(i8* nonnull %dst, i8* nonnull %src, i32 %n) - ret i8* %ret + %ret = call ptr @strncpy(ptr nonnull %dst, ptr nonnull %src, i32 %n) + ret ptr %ret } -define i8* @test2(i8* %dst) { +define ptr @test2(ptr %dst) { ; CHECK-LABEL: @test2( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(5) [[DST:%.*]], i8* noundef nonnull align 1 dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 5, i1 false) -; CHECK-NEXT: ret i8* [[DST]] +; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr noundef nonnull align 1 dereferenceable(5) [[DST:%.*]], ptr noundef nonnull align 1 dereferenceable(6) @hello, i32 5, i1 false) +; CHECK-NEXT: ret ptr [[DST]] ; - %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - %ret = call i8* @strncpy(i8* nonnull %dst, i8* nonnull %src, i32 5) - ret i8* %ret + %ret = call ptr @strncpy(ptr nonnull %dst, ptr nonnull @hello, i32 5) + ret ptr %ret } -define i8* @test3(i8* %dst, i32 %n) { +define ptr @test3(ptr %dst, i32 %n) { ; CHECK-LABEL: @test3( -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* noalias noundef nonnull align 1 dereferenceable(5) [[DST:%.*]], i8 0, i32 5, i1 false) -; CHECK-NEXT: ret i8* [[DST]] +; CHECK-NEXT: call void @llvm.memset.p0.i32(ptr noalias noundef nonnull align 1 dereferenceable(5) [[DST:%.*]], i8 0, i32 5, i1 false) +; CHECK-NEXT: ret ptr [[DST]] ; - %src = getelementptr [1 x i8], [1 x i8]* @null, i32 0, i32 0 - %ret = call i8* @strncpy(i8* noalias nonnull %dst, i8* nonnull %src, i32 5); - ret i8* %ret + %ret = call ptr @strncpy(ptr noalias nonnull %dst, ptr nonnull @null, i32 5); + ret ptr %ret } -define i8* @test4(i8* %dst, i32 %n) { +define ptr @test4(ptr %dst, i32 %n) { ; CHECK-LABEL: @test4( -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* noalias noundef nonnull align 16 dereferenceable(5) [[DST:%.*]], i8 0, i32 5, i1 false) -; CHECK-NEXT: ret i8* [[DST]] +; CHECK-NEXT: call void @llvm.memset.p0.i32(ptr noalias noundef nonnull align 16 dereferenceable(5) [[DST:%.*]], i8 0, i32 5, i1 false) +; CHECK-NEXT: ret ptr [[DST]] ; - %src = getelementptr [1 x i8], [1 x i8]* @null, i32 0, i32 0 - %ret = call i8* @strncpy(i8* align(16) noalias nonnull %dst, i8* nonnull %src, i32 5); - ret i8* %ret + %ret = call ptr @strncpy(ptr align(16) noalias nonnull %dst, ptr nonnull @null, i32 5); + ret ptr %ret } ; Check cases that shouldn't be simplified. define void @test_no_simplify1() { ; CHECK-LABEL: @test_no_simplify1( -; CHECK-NEXT: [[TMP1:%.*]] = call i8* @strncpy(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0), i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([32 x i8], [32 x i8]* @b, i32 0, i32 0), i32 32) +; CHECK-NEXT: [[TMP1:%.*]] = call ptr @strncpy(ptr noundef nonnull @a, ptr noundef nonnull @b, i32 32) ; CHECK-NEXT: ret void ; - %dst = getelementptr [32 x i8], [32 x i8]* @a, i32 0, i32 0 - %src = getelementptr [32 x i8], [32 x i8]* @b, i32 0, i32 0 - call i8* @strncpy(i8* %dst, i8* %src, i32 32) + call ptr @strncpy(ptr @a, ptr @b, i32 32) ret void } define void @test_no_simplify2() { ; CHECK-LABEL: @test_no_simplify2( -; CHECK-NEXT: store i64 478560413032, i64* bitcast ([32 x i8]* @a to i64*), align 1 +; CHECK-NEXT: store i64 478560413032, ptr @a, align 1 ; CHECK-NEXT: ret void ; - %dst = getelementptr [32 x i8], [32 x i8]* @a, i32 0, i32 0 - %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - call i8* @strncpy(i8* %dst, i8* %src, i32 8) + call ptr @strncpy(ptr @a, ptr @hello, i32 8) ret void } -define i8* @test_no_simplify3(i8* %dst, i8* %src, i32 %count) { +define ptr @test_no_simplify3(ptr %dst, ptr %src, i32 %count) { ; CHECK-LABEL: @test_no_simplify3( -; CHECK-NEXT: [[RET:%.*]] = musttail call i8* @strncpy(i8* [[DST:%.*]], i8* [[SRC:%.*]], i32 32) -; CHECK-NEXT: ret i8* [[RET]] +; CHECK-NEXT: [[RET:%.*]] = musttail call ptr @strncpy(ptr [[DST:%.*]], ptr [[SRC:%.*]], i32 32) +; CHECK-NEXT: ret ptr [[RET]] ; - %ret = musttail call i8* @strncpy(i8* %dst, i8* %src, i32 32) - ret i8* %ret + %ret = musttail call ptr @strncpy(ptr %dst, ptr %src, i32 32) + ret ptr %ret } -define i8* @test_no_simplify4(i8* %dst, i8* %src, i32 %count) { +define ptr @test_no_simplify4(ptr %dst, ptr %src, i32 %count) { ; CHECK-LABEL: @test_no_simplify4( -; CHECK-NEXT: [[RET:%.*]] = musttail call i8* @strncpy(i8* [[DST:%.*]], i8* [[SRC:%.*]], i32 6) -; CHECK-NEXT: ret i8* [[RET]] +; CHECK-NEXT: [[RET:%.*]] = musttail call ptr @strncpy(ptr [[DST:%.*]], ptr [[SRC:%.*]], i32 6) +; CHECK-NEXT: ret ptr [[RET]] ; - %ret = musttail call i8* @strncpy(i8* %dst, i8* %src, i32 6) - ret i8* %ret + %ret = musttail call ptr @strncpy(ptr %dst, ptr %src, i32 6) + ret ptr %ret } define void @test_no_incompatible_attr() { ; CHECK-LABEL: @test_no_incompatible_attr( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(6) getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0), i8* noundef nonnull align 1 dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 6, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr noundef nonnull align 1 dereferenceable(6) @a, ptr noundef nonnull align 1 dereferenceable(6) @hello, i32 6, i1 false) ; CHECK-NEXT: ret void ; - %dst = getelementptr [32 x i8], [32 x i8]* @a, i32 0, i32 0 - %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - call i8* @strncpy(i8* %dst, i8* %src, i32 6) + call ptr @strncpy(ptr @a, ptr @hello, i32 6) ret void } diff --git a/llvm/test/Transforms/InstCombine/strncpy-2.ll b/llvm/test/Transforms/InstCombine/strncpy-2.ll --- a/llvm/test/Transforms/InstCombine/strncpy-2.ll +++ b/llvm/test/Transforms/InstCombine/strncpy-2.ll @@ -11,18 +11,16 @@ @hello = constant [6 x i8] c"hello\00" @a = common global [32 x i8] zeroinitializer, align 1 -declare i16 @strncpy(i8*, i8*, i32) +declare i16 @strncpy(ptr, ptr, i32) ; Check that 'strncpy' functions with the wrong prototype aren't simplified. define void @test_no_simplify1() { ; CHECK-LABEL: @test_no_simplify1( -; CHECK-NEXT: [[TMP1:%.*]] = call i16 @strncpy(i8* getelementptr inbounds ([32 x i8], [32 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i32 0, i32 0), i32 6) +; CHECK-NEXT: [[TMP1:%.*]] = call i16 @strncpy(ptr nonnull @a, ptr nonnull @hello, i32 6) ; CHECK-NEXT: ret void ; - %dst = getelementptr [32 x i8], [32 x i8]* @a, i32 0, i32 0 - %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - call i16 @strncpy(i8* %dst, i8* %src, i32 6) + call i16 @strncpy(ptr @a, ptr @hello, i32 6) ret void } diff --git a/llvm/test/Transforms/InstCombine/strncpy-3.ll b/llvm/test/Transforms/InstCombine/strncpy-3.ll --- a/llvm/test/Transforms/InstCombine/strncpy-3.ll +++ b/llvm/test/Transforms/InstCombine/strncpy-3.ll @@ -38,7 +38,7 @@ define void @fill_with_zeros4(ptr %dst) { ; CHECK-LABEL: @fill_with_zeros4( -; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(128) [[DST:%.*]], ptr noundef nonnull align 1 dereferenceable(128) @str.2, i64 128, i1 false) +; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(128) [[DST:%.*]], ptr noundef nonnull align 1 dereferenceable(128) @str.2, i64 128, i1 false) ; CHECK-NEXT: ret void ; tail call ptr @strncpy(ptr %dst, ptr @str3, i64 128) diff --git a/llvm/test/Transforms/InstCombine/strncpy_chk-1.ll b/llvm/test/Transforms/InstCombine/strncpy_chk-1.ll --- a/llvm/test/Transforms/InstCombine/strncpy_chk-1.ll +++ b/llvm/test/Transforms/InstCombine/strncpy_chk-1.ll @@ -12,66 +12,56 @@ ; Check cases where dstlen >= len -define i8* @test_simplify1() { +define ptr @test_simplify1() { ; CHECK-LABEL: @test_simplify1( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* noundef nonnull align 1 dereferenceable(12) getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i1 false) -; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0) +; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr noundef nonnull align 1 dereferenceable(12) @a, ptr noundef nonnull align 1 dereferenceable(12) @.str, i32 12, i1 false) +; CHECK-NEXT: ret ptr @a ; - %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 - %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0, i32 0 - %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 12, i32 60) - ret i8* %ret + %ret = call ptr @__strncpy_chk(ptr @a, ptr @.str, i32 12, i32 60) + ret ptr %ret } -define i8* @test_simplify2() { +define ptr @test_simplify2() { ; CHECK-LABEL: @test_simplify2( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* noundef nonnull align 1 dereferenceable(12) getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i1 false) -; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0) +; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr noundef nonnull align 1 dereferenceable(12) @a, ptr noundef nonnull align 1 dereferenceable(12) @.str, i32 12, i1 false) +; CHECK-NEXT: ret ptr @a ; - %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 - %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0, i32 0 - %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 12, i32 12) - ret i8* %ret + %ret = call ptr @__strncpy_chk(ptr @a, ptr @.str, i32 12, i32 12) + ret ptr %ret } -define i8* @test_simplify3() { +define ptr @test_simplify3() { ; CHECK-LABEL: @test_simplify3( -; CHECK-NEXT: [[STRNCPY:%.*]] = call i8* @strncpy(i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* noundef nonnull dereferenceable(1) getelementptr inbounds ([60 x i8], [60 x i8]* @b, i32 0, i32 0), i32 12) -; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0) +; CHECK-NEXT: [[STRNCPY:%.*]] = call ptr @strncpy(ptr noundef nonnull dereferenceable(1) @a, ptr noundef nonnull dereferenceable(1) @b, i32 12) +; CHECK-NEXT: ret ptr @a ; - %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 - %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0 - %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 12, i32 60) - ret i8* %ret + %ret = call ptr @__strncpy_chk(ptr @a, ptr @b, i32 12, i32 60) + ret ptr %ret } ; Check cases where dstlen < len -define i8* @test_no_simplify1() { +define ptr @test_no_simplify1() { ; CHECK-LABEL: @test_no_simplify1( -; CHECK-NEXT: [[RET:%.*]] = call i8* @__strncpy_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 8, i32 4) -; CHECK-NEXT: ret i8* [[RET]] +; CHECK-NEXT: [[RET:%.*]] = call ptr @__strncpy_chk(ptr nonnull @a, ptr nonnull @.str, i32 8, i32 4) +; CHECK-NEXT: ret ptr [[RET]] ; - %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 - %src = getelementptr inbounds [12 x i8], [12 x i8]* @.str, i32 0, i32 0 - %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 8, i32 4) - ret i8* %ret + %ret = call ptr @__strncpy_chk(ptr @a, ptr @.str, i32 8, i32 4) + ret ptr %ret } -define i8* @test_no_simplify2() { +define ptr @test_no_simplify2() { ; CHECK-LABEL: @test_no_simplify2( -; CHECK-NEXT: [[RET:%.*]] = call i8* @__strncpy_chk(i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* getelementptr inbounds ([60 x i8], [60 x i8]* @b, i32 0, i32 0), i32 8, i32 0) -; CHECK-NEXT: ret i8* [[RET]] +; CHECK-NEXT: [[RET:%.*]] = call ptr @__strncpy_chk(ptr nonnull @a, ptr nonnull @b, i32 8, i32 0) +; CHECK-NEXT: ret ptr [[RET]] ; - %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 - %src = getelementptr inbounds [60 x i8], [60 x i8]* @b, i32 0, i32 0 - %ret = call i8* @__strncpy_chk(i8* %dst, i8* %src, i32 8, i32 0) - ret i8* %ret + %ret = call ptr @__strncpy_chk(ptr @a, ptr @b, i32 8, i32 0) + ret ptr %ret } -declare i8* @__strncpy_chk(i8*, i8*, i32, i32) +declare ptr @__strncpy_chk(ptr, ptr, i32, i32) diff --git a/llvm/test/Transforms/InstCombine/strndup.ll b/llvm/test/Transforms/InstCombine/strndup.ll --- a/llvm/test/Transforms/InstCombine/strndup.ll +++ b/llvm/test/Transforms/InstCombine/strndup.ll @@ -4,64 +4,58 @@ @hello = constant [6 x i8] c"hello\00" @null = constant [1 x i8] zeroinitializer -declare i8* @strndup(i8*, i64) +declare ptr @strndup(ptr, i64) -define i8* @test1() { +define ptr @test1() { ; CHECK-LABEL: @test1( -; CHECK-NEXT: [[STRDUP:%.*]] = call dereferenceable_or_null(1) i8* @strdup(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @null, i64 0, i64 0)) -; CHECK-NEXT: ret i8* [[STRDUP]] +; CHECK-NEXT: [[STRDUP:%.*]] = call dereferenceable_or_null(1) ptr @strdup(ptr nonnull @null) +; CHECK-NEXT: ret ptr [[STRDUP]] ; - %src = getelementptr [1 x i8], [1 x i8]* @null, i32 0, i32 0 - %ret = call i8* @strndup(i8* %src, i64 0) - ret i8* %ret + %ret = call ptr @strndup(ptr @null, i64 0) + ret ptr %ret } -define i8* @test2() { +define ptr @test2() { ; CHECK-LABEL: @test2( -; CHECK-NEXT: [[RET:%.*]] = call dereferenceable_or_null(5) i8* @strndup(i8* dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i64 0, i64 0), i64 4) -; CHECK-NEXT: ret i8* [[RET]] +; CHECK-NEXT: [[RET:%.*]] = call dereferenceable_or_null(5) ptr @strndup(ptr nonnull dereferenceable(6) @hello, i64 4) +; CHECK-NEXT: ret ptr [[RET]] ; - %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - %ret = call i8* @strndup(i8* %src, i64 4) - ret i8* %ret + %ret = call ptr @strndup(ptr @hello, i64 4) + ret ptr %ret } -define i8* @test3() { +define ptr @test3() { ; CHECK-LABEL: @test3( -; CHECK-NEXT: [[STRDUP:%.*]] = call dereferenceable_or_null(6) i8* @strdup(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i64 0, i64 0)) -; CHECK-NEXT: ret i8* [[STRDUP]] +; CHECK-NEXT: [[STRDUP:%.*]] = call dereferenceable_or_null(6) ptr @strdup(ptr nonnull @hello) +; CHECK-NEXT: ret ptr [[STRDUP]] ; - %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - %ret = call i8* @strndup(i8* %src, i64 5) - ret i8* %ret + %ret = call ptr @strndup(ptr @hello, i64 5) + ret ptr %ret } -define i8* @test4() { +define ptr @test4() { ; CHECK-LABEL: @test4( -; CHECK-NEXT: [[STRDUP:%.*]] = call dereferenceable_or_null(6) i8* @strdup(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i64 0, i64 0)) -; CHECK-NEXT: ret i8* [[STRDUP]] +; CHECK-NEXT: [[STRDUP:%.*]] = call dereferenceable_or_null(6) ptr @strdup(ptr nonnull @hello) +; CHECK-NEXT: ret ptr [[STRDUP]] ; - %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - %ret = call i8* @strndup(i8* %src, i64 6) - ret i8* %ret + %ret = call ptr @strndup(ptr @hello, i64 6) + ret ptr %ret } -define i8* @test5() { +define ptr @test5() { ; CHECK-LABEL: @test5( -; CHECK-NEXT: [[STRDUP:%.*]] = call dereferenceable_or_null(6) i8* @strdup(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i64 0, i64 0)) -; CHECK-NEXT: ret i8* [[STRDUP]] +; CHECK-NEXT: [[STRDUP:%.*]] = call dereferenceable_or_null(6) ptr @strdup(ptr nonnull @hello) +; CHECK-NEXT: ret ptr [[STRDUP]] ; - %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - %ret = call i8* @strndup(i8* %src, i64 7) - ret i8* %ret + %ret = call ptr @strndup(ptr @hello, i64 7) + ret ptr %ret } -define i8* @test6(i64 %n) { +define ptr @test6(i64 %n) { ; CHECK-LABEL: @test6( -; CHECK-NEXT: [[RET:%.*]] = call i8* @strndup(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i64 0, i64 0), i64 [[N:%.*]]) -; CHECK-NEXT: ret i8* [[RET]] +; CHECK-NEXT: [[RET:%.*]] = call ptr @strndup(ptr nonnull @hello, i64 [[N:%.*]]) +; CHECK-NEXT: ret ptr [[RET]] ; - %src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0 - %ret = call i8* @strndup(i8* %src, i64 %n) - ret i8* %ret + %ret = call ptr @strndup(ptr @hello, i64 %n) + ret ptr %ret } diff --git a/llvm/test/Transforms/InstCombine/strnlen-2.ll b/llvm/test/Transforms/InstCombine/strnlen-2.ll --- a/llvm/test/Transforms/InstCombine/strnlen-2.ll +++ b/llvm/test/Transforms/InstCombine/strnlen-2.ll @@ -4,7 +4,7 @@ ; ; RUN: opt < %s -passes=instcombine -S | FileCheck %s -declare i64 @strnlen(i8*, i64) +declare i64 @strnlen(ptr, i64) @s3 = constant [4 x i8] c"123\00" @s5 = constant [6 x i8] c"12345\00" @@ -19,9 +19,9 @@ ; CHECK-LABEL: @fold_strnlen_s3_s5_0( ; CHECK-NEXT: ret i64 0 ; - %ptr = select i1 %C, i8* getelementptr ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* getelementptr ([7 x i8], [7 x i8]* @s6, i64 0, i64 0) + %ptr = select i1 %C, ptr @s3, ptr @s6 - %len = call i64 @strnlen(i8* %ptr, i64 0) + %len = call i64 @strnlen(ptr %ptr, i64 0) ret i64 %len } @@ -32,9 +32,9 @@ ; CHECK-LABEL: @fold_strnlen_s3_s5_1( ; CHECK-NEXT: ret i64 1 ; - %ptr = select i1 %C, i8* getelementptr ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* getelementptr ([7 x i8], [7 x i8]* @s6, i64 0, i64 0) + %ptr = select i1 %C, ptr @s3, ptr @s6 - %len = call i64 @strnlen(i8* %ptr, i64 1) + %len = call i64 @strnlen(ptr %ptr, i64 1) ret i64 %len } @@ -43,13 +43,13 @@ define i64 @fold_strnlen_s3_s5_3(i1 %C) { ; CHECK-LABEL: @fold_strnlen_s3_s5_3( -; CHECK-NEXT: [[PTR:%.*]] = select i1 [[C:%.*]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @s6, i64 0, i64 0) -; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull dereferenceable(1) [[PTR]], i64 3) +; CHECK-NEXT: [[PTR:%.*]] = select i1 [[C:%.*]], ptr @s3, ptr @s6 +; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(ptr noundef nonnull [[PTR]], i64 3) ; CHECK-NEXT: ret i64 [[LEN]] ; - %ptr = select i1 %C, i8* getelementptr ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* getelementptr ([7 x i8], [7 x i8]* @s6, i64 0, i64 0) + %ptr = select i1 %C, ptr @s3, ptr @s6 - %len = call i64 @strnlen(i8* %ptr, i64 3) + %len = call i64 @strnlen(ptr %ptr, i64 3) ret i64 %len } @@ -58,13 +58,13 @@ define i64 @fold_strnlen_s3_s5_4(i1 %C) { ; CHECK-LABEL: @fold_strnlen_s3_s5_4( -; CHECK-NEXT: [[PTR:%.*]] = select i1 [[C:%.*]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @s6, i64 0, i64 0) -; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull dereferenceable(1) [[PTR]], i64 4) +; CHECK-NEXT: [[PTR:%.*]] = select i1 [[C:%.*]], ptr @s3, ptr @s6 +; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(ptr noundef nonnull [[PTR]], i64 4) ; CHECK-NEXT: ret i64 [[LEN]] ; - %ptr = select i1 %C, i8* getelementptr ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* getelementptr ([7 x i8], [7 x i8]* @s6, i64 0, i64 0) + %ptr = select i1 %C, ptr @s3, ptr @s6 - %len = call i64 @strnlen(i8* %ptr, i64 4) + %len = call i64 @strnlen(ptr %ptr, i64 4) ret i64 %len } @@ -73,13 +73,13 @@ define i64 @fold_strnlen_s3_s5_5(i1 %C) { ; CHECK-LABEL: @fold_strnlen_s3_s5_5( -; CHECK-NEXT: [[PTR:%.*]] = select i1 [[C:%.*]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @s6, i64 0, i64 0) -; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull dereferenceable(1) [[PTR]], i64 5) +; CHECK-NEXT: [[PTR:%.*]] = select i1 [[C:%.*]], ptr @s3, ptr @s6 +; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(ptr noundef nonnull [[PTR]], i64 5) ; CHECK-NEXT: ret i64 [[LEN]] ; - %ptr = select i1 %C, i8* getelementptr ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* getelementptr ([7 x i8], [7 x i8]* @s6, i64 0, i64 0) + %ptr = select i1 %C, ptr @s3, ptr @s6 - %len = call i64 @strnlen(i8* %ptr, i64 5) + %len = call i64 @strnlen(ptr %ptr, i64 5) ret i64 %len } @@ -88,14 +88,14 @@ define i64 @fold_strnlen_s5_6(i1 %C) { ; CHECK-LABEL: @fold_strnlen_s5_6( -; CHECK-NEXT: [[PTR:%.*]] = select i1 [[C:%.*]], i8* getelementptr inbounds ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @s6, i64 0, i64 0) -; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull dereferenceable(1) [[PTR]], i64 6) +; CHECK-NEXT: [[PTR:%.*]] = select i1 [[C:%.*]], ptr @s5, ptr @s6 +; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(ptr noundef nonnull [[PTR]], i64 6) ; CHECK-NEXT: ret i64 [[LEN]] ; - %ptr = select i1 %C, i8* getelementptr ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i8* getelementptr ([7 x i8], [7 x i8]* @s6, i64 0, i64 0) + %ptr = select i1 %C, ptr @s5, ptr @s6 - %len = call i64 @strnlen(i8* %ptr, i64 6) + %len = call i64 @strnlen(ptr %ptr, i64 6) ret i64 %len } @@ -107,17 +107,17 @@ ; CHECK-LABEL: @fold_strnlen_s3_s5_s7_4( ; CHECK-NEXT: [[X_EQ_3:%.*]] = icmp eq i32 [[X:%.*]], 3 ; CHECK-NEXT: [[X_EQ_5:%.*]] = icmp eq i32 [[X]], 5 -; CHECK-NEXT: [[SEL_X_EQ_5:%.*]] = select i1 [[X_EQ_5]], i8* getelementptr inbounds ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @s7, i64 0, i64 0) -; CHECK-NEXT: [[SEL_X_EQ_3:%.*]] = select i1 [[X_EQ_3]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* [[SEL_X_EQ_5]] -; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strnlen(i8* noundef nonnull dereferenceable(1) [[SEL_X_EQ_3]], i64 4) +; CHECK-NEXT: [[SEL_X_EQ_5:%.*]] = select i1 [[X_EQ_5]], ptr @s5, ptr @s7 +; CHECK-NEXT: [[SEL_X_EQ_3:%.*]] = select i1 [[X_EQ_3]], ptr @s3, ptr [[SEL_X_EQ_5]] +; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strnlen(ptr noundef nonnull [[SEL_X_EQ_3]], i64 4) ; CHECK-NEXT: ret i64 [[LEN]] ; %x_eq_3 = icmp eq i32 %X, 3 %x_eq_5 = icmp eq i32 %X, 5 - %sel_x_eq_5 = select i1 %x_eq_5, i8* getelementptr ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i8* getelementptr ([8 x i8], [8 x i8]* @s7, i64 0, i64 0) - %sel_x_eq_3 = select i1 %x_eq_3, i8* getelementptr ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* %sel_x_eq_5 - %len = tail call i64 @strnlen(i8* %sel_x_eq_3, i64 4) + %sel_x_eq_5 = select i1 %x_eq_5, ptr @s5, ptr @s7 + %sel_x_eq_3 = select i1 %x_eq_3, ptr @s3, ptr %sel_x_eq_5 + %len = tail call i64 @strnlen(ptr %sel_x_eq_3, i64 4) ret i64 %len } @@ -130,17 +130,17 @@ ; CHECK-LABEL: @fold_strnlen_s3_s5_s7_6( ; CHECK-NEXT: [[X_EQ_3:%.*]] = icmp eq i32 [[X:%.*]], 3 ; CHECK-NEXT: [[X_EQ_5:%.*]] = icmp eq i32 [[X]], 5 -; CHECK-NEXT: [[SEL_X_EQ_5:%.*]] = select i1 [[X_EQ_5]], i8* getelementptr inbounds ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @s7, i64 0, i64 0) -; CHECK-NEXT: [[SEL_X_EQ_3:%.*]] = select i1 [[X_EQ_3]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* [[SEL_X_EQ_5]] -; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strnlen(i8* noundef nonnull dereferenceable(1) [[SEL_X_EQ_3]], i64 6) +; CHECK-NEXT: [[SEL_X_EQ_5:%.*]] = select i1 [[X_EQ_5]], ptr @s5, ptr @s7 +; CHECK-NEXT: [[SEL_X_EQ_3:%.*]] = select i1 [[X_EQ_3]], ptr @s3, ptr [[SEL_X_EQ_5]] +; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strnlen(ptr noundef nonnull [[SEL_X_EQ_3]], i64 6) ; CHECK-NEXT: ret i64 [[LEN]] ; %x_eq_3 = icmp eq i32 %X, 3 %x_eq_5 = icmp eq i32 %X, 5 - %sel_x_eq_5 = select i1 %x_eq_5, i8* getelementptr ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i8* getelementptr ([8 x i8], [8 x i8]* @s7, i64 0, i64 0) - %sel_x_eq_3 = select i1 %x_eq_3, i8* getelementptr ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* %sel_x_eq_5 - %len = tail call i64 @strnlen(i8* %sel_x_eq_3, i64 6) + %sel_x_eq_5 = select i1 %x_eq_5, ptr @s5, ptr @s7 + %sel_x_eq_3 = select i1 %x_eq_3, ptr @s3, ptr %sel_x_eq_5 + %len = tail call i64 @strnlen(ptr %sel_x_eq_3, i64 6) ret i64 %len } @@ -153,16 +153,16 @@ ; CHECK-LABEL: @fold_strnlen_s3_s5_s7_8( ; CHECK-NEXT: [[X_EQ_3:%.*]] = icmp eq i32 [[X:%.*]], 3 ; CHECK-NEXT: [[X_EQ_5:%.*]] = icmp eq i32 [[X]], 5 -; CHECK-NEXT: [[SEL_X_EQ_5:%.*]] = select i1 [[X_EQ_5]], i8* getelementptr inbounds ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @s7, i64 0, i64 0) -; CHECK-NEXT: [[SEL_X_EQ_3:%.*]] = select i1 [[X_EQ_3]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* [[SEL_X_EQ_5]] -; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strnlen(i8* noundef nonnull dereferenceable(1) [[SEL_X_EQ_3]], i64 8) +; CHECK-NEXT: [[SEL_X_EQ_5:%.*]] = select i1 [[X_EQ_5]], ptr @s5, ptr @s7 +; CHECK-NEXT: [[SEL_X_EQ_3:%.*]] = select i1 [[X_EQ_3]], ptr @s3, ptr [[SEL_X_EQ_5]] +; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strnlen(ptr noundef nonnull [[SEL_X_EQ_3]], i64 8) ; CHECK-NEXT: ret i64 [[LEN]] ; %x_eq_3 = icmp eq i32 %X, 3 %x_eq_5 = icmp eq i32 %X, 5 - %sel_x_eq_5 = select i1 %x_eq_5, i8* getelementptr ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i8* getelementptr ([8 x i8], [8 x i8]* @s7, i64 0, i64 0) - %sel_x_eq_3 = select i1 %x_eq_3, i8* getelementptr ([4 x i8], [4 x i8]* @s3, i64 0, i64 0), i8* %sel_x_eq_5 - %len = tail call i64 @strnlen(i8* %sel_x_eq_3, i64 8) + %sel_x_eq_5 = select i1 %x_eq_5, ptr @s5, ptr @s7 + %sel_x_eq_3 = select i1 %x_eq_3, ptr @s3, ptr %sel_x_eq_5 + %len = tail call i64 @strnlen(ptr %sel_x_eq_3, i64 8) ret i64 %len } diff --git a/llvm/test/Transforms/InstCombine/strnlen-4.ll b/llvm/test/Transforms/InstCombine/strnlen-4.ll --- a/llvm/test/Transforms/InstCombine/strnlen-4.ll +++ b/llvm/test/Transforms/InstCombine/strnlen-4.ll @@ -4,7 +4,7 @@ ; ; RUN: opt < %s -passes=instcombine -S | FileCheck %s -declare i64 @strnlen(i8*, i64) +declare i64 @strnlen(ptr, i64) @sx = external global [0 x i8] @s3 = constant [4 x i8] c"123\00" @@ -17,15 +17,15 @@ define i64 @fold_strnlen_s3_pi_s5_n(i1 %C, i64 %i, i64 %n) { ; CHECK-LABEL: @fold_strnlen_s3_pi_s5_n( -; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* @s3, i64 0, i64 [[I:%.*]] -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i8* [[PTR]], i8* getelementptr inbounds ([6 x i8], [6 x i8]* @s5, i64 0, i64 0) -; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* [[SEL]], i64 [[N:%.*]]) +; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [4 x i8], ptr @s3, i64 0, i64 [[I:%.*]] +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], ptr [[PTR]], ptr @s5 +; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(ptr nonnull [[SEL]], i64 [[N:%.*]]) ; CHECK-NEXT: ret i64 [[LEN]] ; - %ptr = getelementptr inbounds [4 x i8], [4 x i8]* @s3, i64 0, i64 %i - %sel = select i1 %C, i8* %ptr, i8* getelementptr ([6 x i8], [6 x i8]* @s5, i64 0, i64 0) - %len = call i64 @strnlen(i8* %sel, i64 %n) + %ptr = getelementptr inbounds [4 x i8], ptr @s3, i64 0, i64 %i + %sel = select i1 %C, ptr %ptr, ptr @s5 + %len = call i64 @strnlen(ptr %sel, i64 %n) ret i64 %len } @@ -37,15 +37,15 @@ define i64 @call_strnlen_s3_pi_xbounds_s5_n(i1 %C, i64 %i, i64 %n) { ; CHECK-LABEL: @call_strnlen_s3_pi_xbounds_s5_n( -; CHECK-NEXT: [[PTR:%.*]] = getelementptr [4 x i8], [4 x i8]* @s3, i64 0, i64 [[I:%.*]] -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i8* [[PTR]], i8* getelementptr inbounds ([6 x i8], [6 x i8]* @s5, i64 0, i64 0) -; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* [[SEL]], i64 [[N:%.*]]) +; CHECK-NEXT: [[PTR:%.*]] = getelementptr [4 x i8], ptr @s3, i64 0, i64 [[I:%.*]] +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], ptr [[PTR]], ptr @s5 +; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(ptr [[SEL]], i64 [[N:%.*]]) ; CHECK-NEXT: ret i64 [[LEN]] ; - %ptr = getelementptr [4 x i8], [4 x i8]* @s3, i64 0, i64 %i - %sel = select i1 %C, i8* %ptr, i8* getelementptr ([6 x i8], [6 x i8]* @s5, i64 0, i64 0) - %len = call i64 @strnlen(i8* %sel, i64 %n) + %ptr = getelementptr [4 x i8], ptr @s3, i64 0, i64 %i + %sel = select i1 %C, ptr %ptr, ptr @s5 + %len = call i64 @strnlen(ptr %sel, i64 %n) ret i64 %len } @@ -57,15 +57,15 @@ define i64 @call_strnlen_s3_pi_sx_n(i1 %C, i64 %i, i64 %n) { ; CHECK-LABEL: @call_strnlen_s3_pi_sx_n( -; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* @s3, i64 0, i64 [[I:%.*]] -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i8* [[PTR]], i8* getelementptr inbounds ([0 x i8], [0 x i8]* @sx, i64 0, i64 0) -; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* [[SEL]], i64 [[N:%.*]]) +; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [4 x i8], ptr @s3, i64 0, i64 [[I:%.*]] +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], ptr [[PTR]], ptr @sx +; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(ptr nonnull [[SEL]], i64 [[N:%.*]]) ; CHECK-NEXT: ret i64 [[LEN]] ; - %ptr = getelementptr inbounds [4 x i8], [4 x i8]* @s3, i64 0, i64 %i - %sel = select i1 %C, i8* %ptr, i8* getelementptr ([0 x i8], [0 x i8]* @sx, i64 0, i64 0) - %len = call i64 @strnlen(i8* %sel, i64 %n) + %ptr = getelementptr inbounds [4 x i8], ptr @s3, i64 0, i64 %i + %sel = select i1 %C, ptr %ptr, ptr @sx + %len = call i64 @strnlen(ptr %sel, i64 %n) ret i64 %len } @@ -74,12 +74,12 @@ define i64 @fold_strnlen_s3_s5_pi_n(i1 %C, i64 %i, i64 %n) { ; CHECK-LABEL: @fold_strnlen_s3_s5_pi_n( -; CHECK-NEXT: [[PTR:%.*]] = select i1 [[C:%.*]], i8* getelementptr inbounds ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @s3, i64 0, i64 0) -; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* [[PTR]], i64 [[I:%.*]]) +; CHECK-NEXT: [[PTR:%.*]] = select i1 [[C:%.*]], ptr @s5, ptr @s3 +; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(ptr nonnull [[PTR]], i64 [[I:%.*]]) ; CHECK-NEXT: ret i64 [[LEN]] ; - %ptr = select i1 %C, i8* getelementptr ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i8* getelementptr ([4 x i8], [4 x i8]* @s3, i64 0, i64 0) - %len = call i64 @strnlen(i8* %ptr, i64 %i) + %ptr = select i1 %C, ptr @s5, ptr @s3 + %len = call i64 @strnlen(ptr %ptr, i64 %i) ret i64 %len } diff --git a/llvm/test/Transforms/InstCombine/strnlen-5.ll b/llvm/test/Transforms/InstCombine/strnlen-5.ll --- a/llvm/test/Transforms/InstCombine/strnlen-5.ll +++ b/llvm/test/Transforms/InstCombine/strnlen-5.ll @@ -4,7 +4,7 @@ ; ; RUN: opt < %s -passes=instcombine -S | FileCheck %s -declare i64 @strnlen(i8*, i64) +declare i64 @strnlen(ptr, i64) @ax = external global [0 x i8] @a5 = external global [5 x i8] @@ -18,8 +18,7 @@ ; CHECK-NEXT: ret i1 true ; - %ptr = getelementptr [0 x i8], [0 x i8]* @ax, i64 0, i64 0 - %len = tail call i64 @strnlen(i8* %ptr, i64 0) + %len = tail call i64 @strnlen(ptr @ax, i64 0) %eqz = icmp eq i64 %len, 0 ret i1 %eqz } @@ -32,8 +31,7 @@ ; CHECK-NEXT: ret i1 false ; - %ptr = getelementptr [0 x i8], [0 x i8]* @ax, i64 0, i64 0 - %len = tail call i64 @strnlen(i8* %ptr, i64 0) + %len = tail call i64 @strnlen(ptr @ax, i64 0) %gtz = icmp ugt i64 %len, 0 ret i1 %gtz } @@ -43,13 +41,12 @@ define i1 @fold_strnlen_ax_1_eqz() { ; CHECK-LABEL: @fold_strnlen_ax_1_eqz( -; CHECK-NEXT: [[CHAR0:%.*]] = load i8, i8* getelementptr inbounds ([0 x i8], [0 x i8]* @ax, i64 0, i64 0), align 1 +; CHECK-NEXT: [[CHAR0:%.*]] = load i8, ptr @ax, align 1 ; CHECK-NEXT: [[EQZ:%.*]] = icmp eq i8 [[CHAR0]], 0 ; CHECK-NEXT: ret i1 [[EQZ]] ; - %ptr = getelementptr [0 x i8], [0 x i8]* @ax, i64 0, i64 0 - %len = tail call i64 @strnlen(i8* %ptr, i64 1) + %len = tail call i64 @strnlen(ptr @ax, i64 1) %eqz = icmp eq i64 %len, 0 ret i1 %eqz } @@ -59,13 +56,12 @@ define i1 @fold_strnlen_ax_1_lt1() { ; CHECK-LABEL: @fold_strnlen_ax_1_lt1( -; CHECK-NEXT: [[STRNLEN_CHAR0:%.*]] = load i8, i8* getelementptr inbounds ([0 x i8], [0 x i8]* @ax, i64 0, i64 0), align 1 +; CHECK-NEXT: [[STRNLEN_CHAR0:%.*]] = load i8, ptr @ax, align 1 ; CHECK-NEXT: [[STRNLEN_CHAR0CMP_NOT:%.*]] = icmp eq i8 [[STRNLEN_CHAR0]], 0 ; CHECK-NEXT: ret i1 [[STRNLEN_CHAR0CMP_NOT]] ; - %ptr = getelementptr [0 x i8], [0 x i8]* @ax, i64 0, i64 0 - %len = tail call i64 @strnlen(i8* %ptr, i64 1) + %len = tail call i64 @strnlen(ptr @ax, i64 1) %nez = icmp ult i64 %len, 1 ret i1 %nez } @@ -75,13 +71,12 @@ define i1 @fold_strnlen_ax_1_neqz() { ; CHECK-LABEL: @fold_strnlen_ax_1_neqz( -; CHECK-NEXT: [[CHAR0:%.*]] = load i8, i8* getelementptr inbounds ([0 x i8], [0 x i8]* @ax, i64 0, i64 0), align 1 +; CHECK-NEXT: [[CHAR0:%.*]] = load i8, ptr @ax, align 1 ; CHECK-NEXT: [[NEZ:%.*]] = icmp ne i8 [[CHAR0]], 0 ; CHECK-NEXT: ret i1 [[NEZ]] ; - %ptr = getelementptr [0 x i8], [0 x i8]* @ax, i64 0, i64 0 - %len = tail call i64 @strnlen(i8* %ptr, i64 1) + %len = tail call i64 @strnlen(ptr @ax, i64 1) %nez = icmp ne i64 %len, 0 ret i1 %nez } @@ -91,13 +86,12 @@ define i1 @fold_strnlen_ax_1_gtz() { ; CHECK-LABEL: @fold_strnlen_ax_1_gtz( -; CHECK-NEXT: [[STRNLEN_CHAR0:%.*]] = load i8, i8* getelementptr inbounds ([0 x i8], [0 x i8]* @ax, i64 0, i64 0), align 1 +; CHECK-NEXT: [[STRNLEN_CHAR0:%.*]] = load i8, ptr @ax, align 1 ; CHECK-NEXT: [[STRNLEN_CHAR0CMP:%.*]] = icmp ne i8 [[STRNLEN_CHAR0]], 0 ; CHECK-NEXT: ret i1 [[STRNLEN_CHAR0CMP]] ; - %ptr = getelementptr [0 x i8], [0 x i8]* @ax, i64 0, i64 0 - %len = tail call i64 @strnlen(i8* %ptr, i64 1) + %len = tail call i64 @strnlen(ptr @ax, i64 1) %nez = icmp ugt i64 %len, 0 ret i1 %nez } @@ -107,13 +101,12 @@ define i1 @fold_strnlen_ax_9_eqz() { ; CHECK-LABEL: @fold_strnlen_ax_9_eqz( -; CHECK-NEXT: [[CHAR0:%.*]] = load i8, i8* getelementptr inbounds ([0 x i8], [0 x i8]* @ax, i64 0, i64 0), align 1 +; CHECK-NEXT: [[CHAR0:%.*]] = load i8, ptr @ax, align 1 ; CHECK-NEXT: [[EQZ:%.*]] = icmp eq i8 [[CHAR0]], 0 ; CHECK-NEXT: ret i1 [[EQZ]] ; - %ptr = getelementptr [0 x i8], [0 x i8]* @ax, i64 0, i64 0 - %len = tail call i64 @strnlen(i8* %ptr, i64 9) + %len = tail call i64 @strnlen(ptr @ax, i64 9) %eqz = icmp eq i64 %len, 0 ret i1 %eqz } @@ -123,13 +116,12 @@ define i1 @call_strnlen_ax_n_eqz(i64 %n) { ; CHECK-LABEL: @call_strnlen_ax_n_eqz( -; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strnlen(i8* getelementptr inbounds ([0 x i8], [0 x i8]* @ax, i64 0, i64 0), i64 [[N:%.*]]) +; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strnlen(ptr nonnull @ax, i64 [[N:%.*]]) ; CHECK-NEXT: [[EQZ:%.*]] = icmp eq i64 [[LEN]], 0 ; CHECK-NEXT: ret i1 [[EQZ]] ; - %ptr = getelementptr [0 x i8], [0 x i8]* @ax, i64 0, i64 0 - %len = tail call i64 @strnlen(i8* %ptr, i64 %n) + %len = tail call i64 @strnlen(ptr @ax, i64 %n) %eqz = icmp eq i64 %len, 0 ret i1 %eqz } @@ -139,14 +131,13 @@ define i1 @fold_strnlen_ax_nz_eqz(i64 %n) { ; CHECK-LABEL: @fold_strnlen_ax_nz_eqz( -; CHECK-NEXT: [[CHAR0:%.*]] = load i8, i8* getelementptr inbounds ([0 x i8], [0 x i8]* @ax, i64 0, i64 0), align 1 +; CHECK-NEXT: [[CHAR0:%.*]] = load i8, ptr @ax, align 1 ; CHECK-NEXT: [[EQZ:%.*]] = icmp eq i8 [[CHAR0]], 0 ; CHECK-NEXT: ret i1 [[EQZ]] ; %max = or i64 %n, 1 - %ptr = getelementptr [0 x i8], [0 x i8]* @ax, i64 0, i64 0 - %len = tail call i64 @strnlen(i8* %ptr, i64 %max) + %len = tail call i64 @strnlen(ptr @ax, i64 %max) %eqz = icmp eq i64 %len, 0 ret i1 %eqz } @@ -156,14 +147,13 @@ define i1 @fold_strnlen_ax_nz_gtz(i64 %n) { ; CHECK-LABEL: @fold_strnlen_ax_nz_gtz( -; CHECK-NEXT: [[CHAR0:%.*]] = load i8, i8* getelementptr inbounds ([0 x i8], [0 x i8]* @ax, i64 0, i64 0), align 1 +; CHECK-NEXT: [[CHAR0:%.*]] = load i8, ptr @ax, align 1 ; CHECK-NEXT: [[GTZ:%.*]] = icmp ne i8 [[CHAR0]], 0 ; CHECK-NEXT: ret i1 [[GTZ]] ; %max = or i64 %n, 1 - %ptr = getelementptr [0 x i8], [0 x i8]* @ax, i64 0, i64 0 - %len = tail call i64 @strnlen(i8* %ptr, i64 %max) + %len = tail call i64 @strnlen(ptr @ax, i64 %max) %gtz = icmp ugt i64 %len, 0 ret i1 %gtz } @@ -174,15 +164,15 @@ define i1 @fold_strnlen_a5_pi_nz_eqz(i64 %i, i64 %n) { ; CHECK-LABEL: @fold_strnlen_a5_pi_nz_eqz( -; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [5 x i8], [5 x i8]* @a5, i64 0, i64 [[I:%.*]] -; CHECK-NEXT: [[CHAR0:%.*]] = load i8, i8* [[PTR]], align 1 +; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [5 x i8], ptr @a5, i64 0, i64 [[I:%.*]] +; CHECK-NEXT: [[CHAR0:%.*]] = load i8, ptr [[PTR]], align 1 ; CHECK-NEXT: [[EQZ:%.*]] = icmp eq i8 [[CHAR0]], 0 ; CHECK-NEXT: ret i1 [[EQZ]] ; %nz = or i64 %n, 1 - %ptr = getelementptr inbounds [5 x i8], [5 x i8]* @a5, i64 0, i64 %i - %len = call i64 @strnlen(i8* %ptr, i64 %nz) + %ptr = getelementptr inbounds [5 x i8], ptr @a5, i64 0, i64 %i + %len = call i64 @strnlen(ptr %ptr, i64 %nz) %eqz = icmp eq i64 %len, 0 ret i1 %eqz } @@ -199,8 +189,8 @@ ; %nz = or i64 %n, 1 - %ptr = getelementptr inbounds [6 x i8], [6 x i8]* @s5, i64 0, i64 %i - %len = call i64 @strnlen(i8* %ptr, i64 %nz) + %ptr = getelementptr inbounds [6 x i8], ptr @s5, i64 0, i64 %i + %len = call i64 @strnlen(ptr %ptr, i64 %nz) %eqz = icmp eq i64 %len, 0 ret i1 %eqz } @@ -210,14 +200,14 @@ define i1 @call_strnlen_s5_pi_n_eqz(i64 %i, i64 %n) { ; CHECK-LABEL: @call_strnlen_s5_pi_n_eqz( -; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [6 x i8], [6 x i8]* @s5, i64 0, i64 [[I:%.*]] -; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* nonnull [[PTR]], i64 [[N:%.*]]) +; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [6 x i8], ptr @s5, i64 0, i64 [[I:%.*]] +; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(ptr nonnull [[PTR]], i64 [[N:%.*]]) ; CHECK-NEXT: [[EQZ:%.*]] = icmp eq i64 [[LEN]], 0 ; CHECK-NEXT: ret i1 [[EQZ]] ; - %ptr = getelementptr inbounds [6 x i8], [6 x i8]* @s5, i64 0, i64 %i - %len = call i64 @strnlen(i8* %ptr, i64 %n) + %ptr = getelementptr inbounds [6 x i8], ptr @s5, i64 0, i64 %i + %len = call i64 @strnlen(ptr %ptr, i64 %n) %eqz = icmp eq i64 %len, 0 ret i1 %eqz }