1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4; Verify that an excessive size to strncmp() isn't truncated to an in-bounds 5; value that results in the call being incorrectly folded (as might happen 6; when LLVM is compiled in ILP32 mode). 7 8declare i32 @strncmp(ptr, ptr, i64) 9 10@ax = external global [0 x i8] 11@bx = external global [0 x i8] 12 13@a12345 = constant [5 x i8] c"\01\02\03\04\05" 14@a123456 = constant [6 x i8] c"\01\02\03\04\05\06" 15 16 17; Do not fold strncmp(ax, bx, UINT_MAX + (size_t)1) to 0. 18 19define i32 @call_strncmp_ax_bx_uimax_p1() { 20; CHECK-LABEL: @call_strncmp_ax_bx_uimax_p1( 21; CHECK-NEXT: [[RES:%.*]] = call i32 @strncmp(ptr noundef nonnull dereferenceable(1) @ax, ptr noundef nonnull dereferenceable(1) @bx, i64 4294967296) 22; CHECK-NEXT: ret i32 [[RES]] 23; 24 25 %res = call i32 @strncmp(ptr @ax, ptr @bx, i64 4294967296) 26 ret i32 %res 27} 28 29 30; Do not fold strncmp(ax, bx, UINT_MAX + (size_t)2) to *ax - *bx. 31 32define i32 @call_strncmp_ax_bx_uimax_p2() { 33; CHECK-LABEL: @call_strncmp_ax_bx_uimax_p2( 34; CHECK-NEXT: [[RES:%.*]] = call i32 @strncmp(ptr noundef nonnull dereferenceable(1) @ax, ptr noundef nonnull dereferenceable(1) @bx, i64 4294967296) 35; CHECK-NEXT: ret i32 [[RES]] 36; 37 38 %res = call i32 @strncmp(ptr @ax, ptr @bx, i64 4294967296) 39 ret i32 %res 40} 41 42 43; Fold strncmp(a12345, a123456, UINT_MAX + (size_t)2) to -1 (and not to 0). 44 45define i32 @fold_strncmp_a12345_2_uimax_p2() { 46; CHECK-LABEL: @fold_strncmp_a12345_2_uimax_p2( 47; CHECK-NEXT: ret i32 -1 48; 49 50 %res = call i32 @strncmp(ptr @a12345, ptr @a123456, i64 4294967297) 51 ret i32 %res 52} 53 54 55; Fold strncmp(a123456, a12345, UINT_MAX + (size_t)3) to +1 (and not to 0). 56 57define i32 @fold_strncmp_a12345_2_uimax_p3() { 58; CHECK-LABEL: @fold_strncmp_a12345_2_uimax_p3( 59; CHECK-NEXT: ret i32 1 60; 61 62 %res = call i32 @strncmp(ptr @a123456, ptr @a12345, i64 4294967298) 63 ret i32 %res 64} 65