
If nonnull is already set, we currently skip setting both nonnull and dereferenceable. Make these independent, to avoid regressions when additional nonnull attributes are inferred earlier.
493 lines
20 KiB
LLVM
493 lines
20 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
|
|
|
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
|
|
|
@key = constant [4 x i8] c"key\00", align 1
|
|
@abc = constant [8 x i8] c"abc\00de\00\00", align 1
|
|
|
|
declare void @use(i32)
|
|
|
|
define i32 @strcmp_memcmp(ptr dereferenceable (12) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strcmp_memcmp(
|
|
; 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]]
|
|
;
|
|
%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(ptr nocapture, ptr nocapture)
|
|
|
|
define i32 @strcmp_memcmp2(ptr dereferenceable (12) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strcmp_memcmp2(
|
|
; 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]]
|
|
;
|
|
%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(ptr dereferenceable (12) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strcmp_memcmp3(
|
|
; 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]]
|
|
;
|
|
%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(ptr dereferenceable (12) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strcmp_memcmp4(
|
|
; 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]]
|
|
;
|
|
%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(ptr dereferenceable (5) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strcmp_memcmp5(
|
|
; 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]]
|
|
;
|
|
%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(ptr dereferenceable (12) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strcmp_memcmp6(
|
|
; 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]]
|
|
;
|
|
%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(ptr dereferenceable (12) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strcmp_memcmp7(
|
|
; 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]]
|
|
;
|
|
%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(ptr dereferenceable (4) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strcmp_memcmp8(
|
|
; 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]]
|
|
;
|
|
%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(ptr dereferenceable (12) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strcmp_memcmp9(
|
|
; 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]]
|
|
;
|
|
%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(ptr dereferenceable (12) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strncmp_memcmp(
|
|
; 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]]
|
|
;
|
|
%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(ptr nocapture, ptr nocapture, i64)
|
|
|
|
define i32 @strncmp_memcmp2(ptr dereferenceable (12) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strncmp_memcmp2(
|
|
; 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]]
|
|
;
|
|
%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(ptr dereferenceable (12) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strncmp_memcmp3(
|
|
; 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]]
|
|
;
|
|
%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(ptr dereferenceable (12) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strncmp_memcmp4(
|
|
; 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]]
|
|
;
|
|
%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(ptr dereferenceable (12) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strncmp_memcmp5(
|
|
; 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]]
|
|
;
|
|
%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(ptr dereferenceable (12) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strncmp_memcmp6(
|
|
; 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]]
|
|
;
|
|
%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(ptr dereferenceable (12) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strncmp_memcmp7(
|
|
; 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]]
|
|
;
|
|
%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(ptr dereferenceable (12) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strncmp_memcmp8(
|
|
; 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]]
|
|
;
|
|
%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(ptr dereferenceable (12) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strncmp_memcmp9(
|
|
; 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]]
|
|
;
|
|
%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(ptr dereferenceable (12) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strncmp_memcmp10(
|
|
; 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]]
|
|
;
|
|
%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(ptr dereferenceable (12) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strncmp_memcmp11(
|
|
; 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]]
|
|
;
|
|
%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(ptr dereferenceable (12) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strncmp_memcmp12(
|
|
; 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]]
|
|
;
|
|
%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(ptr dereferenceable (12) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strncmp_memcmp13(
|
|
; 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]]
|
|
;
|
|
%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(ptr dereferenceable (12) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strncmp_memcmp14(
|
|
; 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]]
|
|
;
|
|
%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(ptr dereferenceable (12) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strcmp_memcmp_bad(
|
|
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr noundef nonnull dereferenceable(1) [[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]]
|
|
;
|
|
%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(ptr dereferenceable (12) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strcmp_memcmp_bad2(
|
|
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(1) [[BUF:%.*]])
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[CALL]], 3
|
|
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
|
; CHECK-NEXT: ret i32 [[CONV]]
|
|
;
|
|
%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(ptr dereferenceable (12) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strcmp_memcmp_bad3(
|
|
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr noundef nonnull dereferenceable(1) [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key)
|
|
; CHECK-NEXT: ret i32 [[CALL]]
|
|
;
|
|
%call = call i32 @strcmp(ptr nonnull %buf, ptr @key)
|
|
ret i32 %call
|
|
}
|
|
|
|
|
|
define i32 @strcmp_memcmp_bad4(ptr nocapture readonly %buf) nofree nosync {
|
|
; CHECK-LABEL: @strcmp_memcmp_bad4(
|
|
; 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(ptr @key, ptr %buf)
|
|
%cmp = icmp eq i32 %call, 0
|
|
%conv = zext i1 %cmp to i32
|
|
ret i32 %conv
|
|
}
|
|
|
|
|
|
define i32 @strcmp_memcmp_bad5(ptr dereferenceable (3) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strcmp_memcmp_bad5(
|
|
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr noundef nonnull dereferenceable(1) [[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]]
|
|
;
|
|
%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(ptr dereferenceable (4) %buf, ptr nocapture readonly %k) nofree nosync {
|
|
; CHECK-LABEL: @strcmp_memcmp_bad6(
|
|
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr noundef nonnull dereferenceable(1) [[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]]
|
|
;
|
|
%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(ptr nocapture readonly %k) nofree nosync {
|
|
; CHECK-LABEL: @strcmp_memcmp_bad7(
|
|
; 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(ptr @key, ptr %k)
|
|
%cmp = icmp eq i32 %call, 0
|
|
%conv = zext i1 %cmp to i32
|
|
ret i32 %conv
|
|
}
|
|
|
|
define i32 @strcmp_memcmp_bad8(ptr dereferenceable (4) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strcmp_memcmp_bad8(
|
|
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr noundef nonnull dereferenceable(1) [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key)
|
|
; CHECK-NEXT: tail call void @use(i32 [[CALL]])
|
|
; CHECK-NEXT: ret i32 0
|
|
;
|
|
%call = call i32 @strcmp(ptr nonnull %buf, ptr @key)
|
|
tail call void @use(i32 %call)
|
|
ret i32 0
|
|
}
|
|
|
|
define i32 @strncmp_memcmp_bad(ptr dereferenceable (12) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strncmp_memcmp_bad(
|
|
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strncmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(1) [[BUF:%.*]], i64 5)
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CALL]], 3
|
|
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
|
; CHECK-NEXT: ret i32 [[CONV]]
|
|
;
|
|
%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(ptr dereferenceable (12) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strncmp_memcmp_bad1(
|
|
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strncmp(ptr noundef nonnull dereferenceable(4) @key, ptr noundef nonnull dereferenceable(1) [[BUF:%.*]], i64 5)
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[CALL]], 3
|
|
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
|
; CHECK-NEXT: ret i32 [[CONV]]
|
|
;
|
|
%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(ptr dereferenceable (12) %buf, i64 %n) nofree nosync {
|
|
; CHECK-LABEL: @strncmp_memcmp_bad2(
|
|
; 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]]
|
|
;
|
|
%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(ptr nocapture readonly %k) nofree nosync {
|
|
; CHECK-LABEL: @strncmp_memcmp_bad3(
|
|
; 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(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(ptr dereferenceable (4) %buf) nofree nosync {
|
|
; CHECK-LABEL: @strncmp_memcmp_bad4(
|
|
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strncmp(ptr noundef nonnull dereferenceable(1) [[BUF:%.*]], ptr noundef nonnull dereferenceable(4) @key, i64 2)
|
|
; CHECK-NEXT: tail call void @use(i32 [[CALL]])
|
|
; CHECK-NEXT: ret i32 0
|
|
;
|
|
%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(ptr dereferenceable (12) %buf) sanitize_memory {
|
|
; CHECK-LABEL: @strcmp_memcmp_msan(
|
|
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr noundef nonnull dereferenceable(1) [[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]]
|
|
;
|
|
%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(ptr nocapture, ptr nocapture, i64)
|