forked from OSchip/llvm-project
[InstCombine] Transform str(n)cmp to memcmp
Summary: Motivation examples: int strcmp_memcmp() { char buf[12]; return strcmp(buf, "key") == 0; } int strcmp_memcmp2() { char buf[12]; return strcmp(buf, "key") != 0; } int strncmp_memcmp() { char buf[12]; return strncmp(buf, "key", 3) == 0; } can be turned to memcmp. See test file for more cases. Reviewers: efriedma Reviewed By: efriedma Subscribers: spatel, llvm-commits Differential Revision: https://reviews.llvm.org/D50233 llvm-svn: 339410
This commit is contained in:
parent
4351f04895
commit
909889b2cb
|
@ -22,6 +22,7 @@
|
|||
#include "llvm/Transforms/Utils/Local.h"
|
||||
#include "llvm/Analysis/ValueTracking.h"
|
||||
#include "llvm/Analysis/CaptureTracking.h"
|
||||
#include "llvm/Analysis/Loads.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
|
@ -150,6 +151,29 @@ static bool isLocallyOpenedFile(Value *File, CallInst *CI, IRBuilder<> &B,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool isOnlyUsedInComparisonWithZero(Value *V) {
|
||||
for (User *U : V->users()) {
|
||||
if (ICmpInst *IC = dyn_cast<ICmpInst>(U))
|
||||
if (Constant *C = dyn_cast<Constant>(IC->getOperand(1)))
|
||||
if (C->isNullValue())
|
||||
continue;
|
||||
// Unknown instruction.
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool canTransformToMemCmp(CallInst *CI, Value *Str, uint64_t Len,
|
||||
const DataLayout &DL) {
|
||||
if (!isOnlyUsedInComparisonWithZero(CI))
|
||||
return false;
|
||||
|
||||
if (!isDereferenceableAndAlignedPointer(Str, 1, APInt(64, Len), DL))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// String and Memory Library Call Optimizations
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -322,6 +346,21 @@ Value *LibCallSimplifier::optimizeStrCmp(CallInst *CI, IRBuilder<> &B) {
|
|||
B, DL, TLI);
|
||||
}
|
||||
|
||||
// strcmp to memcmp
|
||||
if (!HasStr1 && HasStr2) {
|
||||
if (canTransformToMemCmp(CI, Str1P, Len2, DL))
|
||||
return emitMemCmp(
|
||||
Str1P, Str2P,
|
||||
ConstantInt::get(DL.getIntPtrType(CI->getContext()), Len2), B, DL,
|
||||
TLI);
|
||||
} else if (HasStr1 && !HasStr2) {
|
||||
if (canTransformToMemCmp(CI, Str2P, Len1, DL))
|
||||
return emitMemCmp(
|
||||
Str1P, Str2P,
|
||||
ConstantInt::get(DL.getIntPtrType(CI->getContext()), Len1), B, DL,
|
||||
TLI);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -361,6 +400,26 @@ Value *LibCallSimplifier::optimizeStrNCmp(CallInst *CI, IRBuilder<> &B) {
|
|||
if (HasStr2 && Str2.empty()) // strncmp(x, "", n) -> *x
|
||||
return B.CreateZExt(B.CreateLoad(Str1P, "strcmpload"), CI->getType());
|
||||
|
||||
uint64_t Len1 = GetStringLength(Str1P);
|
||||
uint64_t Len2 = GetStringLength(Str2P);
|
||||
|
||||
// strncmp to memcmp
|
||||
if (!HasStr1 && HasStr2) {
|
||||
Len2 = std::min(Len2, Length);
|
||||
if (canTransformToMemCmp(CI, Str1P, Len2, DL))
|
||||
return emitMemCmp(
|
||||
Str1P, Str2P,
|
||||
ConstantInt::get(DL.getIntPtrType(CI->getContext()), Len2), B, DL,
|
||||
TLI);
|
||||
} else if (HasStr1 && !HasStr2) {
|
||||
Len1 = std::min(Len1, Length);
|
||||
if (canTransformToMemCmp(CI, Str2P, Len1, DL))
|
||||
return emitMemCmp(
|
||||
Str1P, Str2P,
|
||||
ConstantInt::get(DL.getIntPtrType(CI->getContext()), Len1), B, DL,
|
||||
TLI);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,8 +11,8 @@ declare void @use(i32)
|
|||
define i32 @strcmp_memcmp([12 x i8]* dereferenceable (12) %buf) {
|
||||
; CHECK-LABEL: @strcmp_memcmp(
|
||||
; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0))
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
|
||||
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
|
@ -28,8 +28,8 @@ declare i32 @strcmp(i8* nocapture, i8* nocapture)
|
|||
define i32 @strcmp_memcmp2([12 x i8]* dereferenceable (12) %buf) {
|
||||
; CHECK-LABEL: @strcmp_memcmp2(
|
||||
; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull [[STRING]])
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
|
||||
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull [[STRING]], i64 4)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
|
@ -43,8 +43,8 @@ define i32 @strcmp_memcmp2([12 x i8]* dereferenceable (12) %buf) {
|
|||
define i32 @strcmp_memcmp3([12 x i8]* dereferenceable (12) %buf) {
|
||||
; CHECK-LABEL: @strcmp_memcmp3(
|
||||
; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0))
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[CALL]], 0
|
||||
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[MEMCMP]], 0
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
|
@ -58,8 +58,8 @@ define i32 @strcmp_memcmp3([12 x i8]* dereferenceable (12) %buf) {
|
|||
define i32 @strcmp_memcmp4([12 x i8]* dereferenceable (12) %buf) {
|
||||
; CHECK-LABEL: @strcmp_memcmp4(
|
||||
; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull [[STRING]])
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[CALL]], 0
|
||||
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull [[STRING]], i64 4)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[MEMCMP]], 0
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
|
@ -73,8 +73,8 @@ define i32 @strcmp_memcmp4([12 x i8]* dereferenceable (12) %buf) {
|
|||
define i32 @strcmp_memcmp5([5 x i8]* dereferenceable (5) %buf) {
|
||||
; CHECK-LABEL: @strcmp_memcmp5(
|
||||
; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [5 x i8], [5 x i8]* [[BUF:%.*]], i64 0, i64 0
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(i8* nonnull align 1 [[STRING]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0))
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
|
||||
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
|
@ -88,8 +88,8 @@ define i32 @strcmp_memcmp5([5 x i8]* dereferenceable (5) %buf) {
|
|||
define i32 @strcmp_memcmp6([12 x i8]* dereferenceable (12) %buf) {
|
||||
; CHECK-LABEL: @strcmp_memcmp6(
|
||||
; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0))
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CALL]], 0
|
||||
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[MEMCMP]], 0
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
|
@ -103,9 +103,9 @@ define i32 @strcmp_memcmp6([12 x i8]* dereferenceable (12) %buf) {
|
|||
define i32 @strcmp_memcmp7([12 x i8]* dereferenceable (12) %buf) {
|
||||
; CHECK-LABEL: @strcmp_memcmp7(
|
||||
; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull [[STRING]])
|
||||
; CHECK-NEXT: [[CALL_LOBIT:%.*]] = lshr i32 [[CALL]], 31
|
||||
; CHECK-NEXT: ret i32 [[CALL_LOBIT]]
|
||||
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull [[STRING]], 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)
|
||||
|
@ -117,8 +117,8 @@ define i32 @strcmp_memcmp7([12 x i8]* dereferenceable (12) %buf) {
|
|||
define i32 @strcmp_memcmp8([4 x i8]* dereferenceable (4) %buf) {
|
||||
; CHECK-LABEL: @strcmp_memcmp8(
|
||||
; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* [[BUF:%.*]], i64 0, i64 0
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0))
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
|
||||
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
|
@ -132,8 +132,8 @@ define i32 @strcmp_memcmp8([4 x i8]* dereferenceable (4) %buf) {
|
|||
define i32 @strcmp_memcmp9([12 x i8]* dereferenceable (12) %buf) {
|
||||
; CHECK-LABEL: @strcmp_memcmp9(
|
||||
; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([8 x i8], [8 x i8]* @abc, i64 0, i64 0))
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
|
||||
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([8 x i8], [8 x i8]* @abc, i64 0, i64 0), i64 4)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
|
@ -148,8 +148,8 @@ define i32 @strcmp_memcmp9([12 x i8]* dereferenceable (12) %buf) {
|
|||
define i32 @strncmp_memcmp([12 x i8]* dereferenceable (12) %buf) {
|
||||
; CHECK-LABEL: @strncmp_memcmp(
|
||||
; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strncmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 2)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
|
||||
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 2)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
|
@ -165,8 +165,8 @@ declare i32 @strncmp(i8* nocapture, i8* nocapture, i64)
|
|||
define i32 @strncmp_memcmp2([12 x i8]* dereferenceable (12) %buf) {
|
||||
; CHECK-LABEL: @strncmp_memcmp2(
|
||||
; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strncmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 11)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[CALL]], 0
|
||||
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[MEMCMP]], 0
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
|
@ -180,8 +180,8 @@ define i32 @strncmp_memcmp2([12 x i8]* dereferenceable (12) %buf) {
|
|||
define i32 @strncmp_memcmp3([12 x i8]* dereferenceable (12) %buf) {
|
||||
; CHECK-LABEL: @strncmp_memcmp3(
|
||||
; 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 11)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
|
||||
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull [[STRING]], i64 4)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
|
@ -195,8 +195,8 @@ define i32 @strncmp_memcmp3([12 x i8]* dereferenceable (12) %buf) {
|
|||
define i32 @strncmp_memcmp4([12 x i8]* dereferenceable (12) %buf) {
|
||||
; CHECK-LABEL: @strncmp_memcmp4(
|
||||
; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strncmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 5)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
|
||||
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
|
@ -210,8 +210,8 @@ define i32 @strncmp_memcmp4([12 x i8]* dereferenceable (12) %buf) {
|
|||
define i32 @strncmp_memcmp5([12 x i8]* dereferenceable (12) %buf) {
|
||||
; CHECK-LABEL: @strncmp_memcmp5(
|
||||
; 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 5)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
|
||||
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull [[STRING]], i64 4)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
|
@ -226,8 +226,8 @@ define i32 @strncmp_memcmp5([12 x i8]* dereferenceable (12) %buf) {
|
|||
define i32 @strncmp_memcmp6([12 x i8]* dereferenceable (12) %buf) {
|
||||
; CHECK-LABEL: @strncmp_memcmp6(
|
||||
; 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 5)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[CALL]], 0
|
||||
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull [[STRING]], i64 4)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[MEMCMP]], 0
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
|
@ -241,8 +241,8 @@ define i32 @strncmp_memcmp6([12 x i8]* dereferenceable (12) %buf) {
|
|||
define i32 @strncmp_memcmp7([12 x i8]* dereferenceable (12) %buf) {
|
||||
; CHECK-LABEL: @strncmp_memcmp7(
|
||||
; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strncmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
|
||||
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 4)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
|
@ -256,8 +256,8 @@ define i32 @strncmp_memcmp7([12 x i8]* dereferenceable (12) %buf) {
|
|||
define i32 @strncmp_memcmp8([12 x i8]* dereferenceable (12) %buf) {
|
||||
; CHECK-LABEL: @strncmp_memcmp8(
|
||||
; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strncmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 3)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
|
||||
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i64 3)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
|
@ -271,8 +271,8 @@ define i32 @strncmp_memcmp8([12 x i8]* dereferenceable (12) %buf) {
|
|||
define i32 @strncmp_memcmp9([12 x i8]* dereferenceable (12) %buf) {
|
||||
; CHECK-LABEL: @strncmp_memcmp9(
|
||||
; 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 5)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CALL]], 0
|
||||
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull [[STRING]], i64 4)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[MEMCMP]], 0
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
|
@ -286,9 +286,9 @@ define i32 @strncmp_memcmp9([12 x i8]* dereferenceable (12) %buf) {
|
|||
define i32 @strncmp_memcmp10([12 x i8]* dereferenceable (12) %buf) {
|
||||
; CHECK-LABEL: @strncmp_memcmp10(
|
||||
; 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 5)
|
||||
; CHECK-NEXT: [[CALL_LOBIT:%.*]] = lshr i32 [[CALL]], 31
|
||||
; CHECK-NEXT: ret i32 [[CALL_LOBIT]]
|
||||
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull [[STRING]], 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)
|
||||
|
@ -300,8 +300,8 @@ define i32 @strncmp_memcmp10([12 x i8]* dereferenceable (12) %buf) {
|
|||
define i32 @strncmp_memcmp11([12 x i8]* dereferenceable (12) %buf) {
|
||||
; CHECK-LABEL: @strncmp_memcmp11(
|
||||
; 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 12)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
|
||||
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull [[STRING]], i64 4)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
|
@ -315,8 +315,8 @@ define i32 @strncmp_memcmp11([12 x i8]* dereferenceable (12) %buf) {
|
|||
define i32 @strncmp_memcmp12([12 x i8]* dereferenceable (12) %buf) {
|
||||
; CHECK-LABEL: @strncmp_memcmp12(
|
||||
; 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 12)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
|
||||
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull [[STRING]], i64 4)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
|
@ -330,8 +330,8 @@ define i32 @strncmp_memcmp12([12 x i8]* dereferenceable (12) %buf) {
|
|||
define i32 @strncmp_memcmp13([12 x i8]* dereferenceable (12) %buf) {
|
||||
; CHECK-LABEL: @strncmp_memcmp13(
|
||||
; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strncmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([8 x i8], [8 x i8]* @abc, i64 0, i64 0), i64 2)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
|
||||
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([8 x i8], [8 x i8]* @abc, i64 0, i64 0), i64 2)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
|
@ -345,8 +345,8 @@ define i32 @strncmp_memcmp13([12 x i8]* dereferenceable (12) %buf) {
|
|||
define i32 @strncmp_memcmp14([12 x i8]* dereferenceable (12) %buf) {
|
||||
; CHECK-LABEL: @strncmp_memcmp14(
|
||||
; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0
|
||||
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strncmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([8 x i8], [8 x i8]* @abc, i64 0, i64 0), i64 12)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
|
||||
; CHECK-NEXT: [[MEMCMP:%.*]] = call i32 @memcmp(i8* nonnull [[STRING]], i8* getelementptr inbounds ([8 x i8], [8 x i8]* @abc, i64 0, i64 0), i64 4)
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[MEMCMP]], 0
|
||||
; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
|
||||
; CHECK-NEXT: ret i32 [[CONV]]
|
||||
;
|
||||
|
|
Loading…
Reference in New Issue