Fold strcmp for short string literals with size 2. Depends D155742. Differential Revision: https://reviews.llvm.org/D155743
405 lines
18 KiB
LLVM
405 lines
18 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt < %s -passes=aggressive-instcombine -S | FileCheck %s
|
|
|
|
declare i32 @strcmp(ptr, ptr)
|
|
|
|
@s0 = constant [1 x i8] c"\00"
|
|
@s1 = constant [2 x i8] c"0\00"
|
|
@s2 = constant [3 x i8] c"01\00"
|
|
@s3 = constant [4 x i8] c"012\00"
|
|
@s4 = constant [5 x i8] c"0123\00"
|
|
|
|
; Expand strcmp(C, "x"), strcmp(C, "xy").
|
|
|
|
define i1 @expand_strcmp_s0(ptr %C) {
|
|
; CHECK-LABEL: @expand_strcmp_s0(
|
|
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr @s0)
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%call = call i32 @strcmp(ptr %C, ptr @s0)
|
|
%cmp = icmp eq i32 %call, 0
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @expand_strcmp_eq_s1(ptr %C) {
|
|
; CHECK-LABEL: @expand_strcmp_eq_s1(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
|
|
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
|
|
; CHECK-NEXT: [[TMP3:%.*]] = sub nsw i32 [[TMP2]], 48
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
|
|
; CHECK-NEXT: br i1 [[TMP4]], label [[STRCMP_EXPAND_SUB_IS_ZERO:%.*]], label [[STRCMP_EXPAND_SUB_JOIN:%.*]]
|
|
; CHECK: strcmp_expand_sub_is_zero:
|
|
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
|
|
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
|
|
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
|
|
; CHECK-NEXT: br label [[STRCMP_EXPAND_SUB_JOIN]]
|
|
; CHECK: strcmp_expand_sub_join:
|
|
; CHECK-NEXT: [[TMP8:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP7]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP8]], 0
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%call = call i32 @strcmp(ptr %C, ptr @s1)
|
|
%cmp = icmp eq i32 %call, 0
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @expand_strcmp_eq_s1_commuted(ptr %C) {
|
|
; CHECK-LABEL: @expand_strcmp_eq_s1_commuted(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
|
|
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
|
|
; CHECK-NEXT: [[TMP3:%.*]] = sub nsw i32 [[TMP2]], 48
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
|
|
; CHECK-NEXT: br i1 [[TMP4]], label [[STRCMP_EXPAND_SUB_IS_ZERO:%.*]], label [[STRCMP_EXPAND_SUB_JOIN:%.*]]
|
|
; CHECK: strcmp_expand_sub_is_zero:
|
|
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
|
|
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
|
|
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
|
|
; CHECK-NEXT: br label [[STRCMP_EXPAND_SUB_JOIN]]
|
|
; CHECK: strcmp_expand_sub_join:
|
|
; CHECK-NEXT: [[TMP8:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP7]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP8]], 0
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%call = call i32 @strcmp(ptr @s1, ptr %C)
|
|
%cmp = icmp eq i32 %call, 0
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @expand_strcmp_ne_s1(ptr %C) {
|
|
; CHECK-LABEL: @expand_strcmp_ne_s1(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
|
|
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
|
|
; CHECK-NEXT: [[TMP3:%.*]] = sub nsw i32 [[TMP2]], 48
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
|
|
; CHECK-NEXT: br i1 [[TMP4]], label [[STRCMP_EXPAND_SUB_IS_ZERO:%.*]], label [[STRCMP_EXPAND_SUB_JOIN:%.*]]
|
|
; CHECK: strcmp_expand_sub_is_zero:
|
|
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
|
|
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
|
|
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
|
|
; CHECK-NEXT: br label [[STRCMP_EXPAND_SUB_JOIN]]
|
|
; CHECK: strcmp_expand_sub_join:
|
|
; CHECK-NEXT: [[TMP8:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP7]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP8]], 0
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%call = call i32 @strcmp(ptr %C, ptr @s1)
|
|
%cmp = icmp ne i32 %call, 0
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @expand_strcmp_sgt_s1(ptr %C) {
|
|
; CHECK-LABEL: @expand_strcmp_sgt_s1(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
|
|
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
|
|
; CHECK-NEXT: [[TMP3:%.*]] = sub nsw i32 [[TMP2]], 48
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
|
|
; CHECK-NEXT: br i1 [[TMP4]], label [[STRCMP_EXPAND_SUB_IS_ZERO:%.*]], label [[STRCMP_EXPAND_SUB_JOIN:%.*]]
|
|
; CHECK: strcmp_expand_sub_is_zero:
|
|
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
|
|
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
|
|
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
|
|
; CHECK-NEXT: br label [[STRCMP_EXPAND_SUB_JOIN]]
|
|
; CHECK: strcmp_expand_sub_join:
|
|
; CHECK-NEXT: [[TMP8:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP7]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP8]], 0
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%call = call i32 @strcmp(ptr %C, ptr @s1)
|
|
%cmp = icmp sgt i32 %call, 0
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @expand_strcmp_sge_s1(ptr %C) {
|
|
; CHECK-LABEL: @expand_strcmp_sge_s1(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
|
|
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
|
|
; CHECK-NEXT: [[TMP3:%.*]] = sub nsw i32 [[TMP2]], 48
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
|
|
; CHECK-NEXT: br i1 [[TMP4]], label [[STRCMP_EXPAND_SUB_IS_ZERO:%.*]], label [[STRCMP_EXPAND_SUB_JOIN:%.*]]
|
|
; CHECK: strcmp_expand_sub_is_zero:
|
|
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
|
|
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
|
|
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
|
|
; CHECK-NEXT: br label [[STRCMP_EXPAND_SUB_JOIN]]
|
|
; CHECK: strcmp_expand_sub_join:
|
|
; CHECK-NEXT: [[TMP8:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP7]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[TMP8]], 0
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%call = call i32 @strcmp(ptr %C, ptr @s1)
|
|
%cmp = icmp sge i32 %call, 0
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @expand_strcmp_slt_s1(ptr %C) {
|
|
; CHECK-LABEL: @expand_strcmp_slt_s1(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
|
|
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
|
|
; CHECK-NEXT: [[TMP3:%.*]] = sub nsw i32 [[TMP2]], 48
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
|
|
; CHECK-NEXT: br i1 [[TMP4]], label [[STRCMP_EXPAND_SUB_IS_ZERO:%.*]], label [[STRCMP_EXPAND_SUB_JOIN:%.*]]
|
|
; CHECK: strcmp_expand_sub_is_zero:
|
|
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
|
|
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
|
|
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
|
|
; CHECK-NEXT: br label [[STRCMP_EXPAND_SUB_JOIN]]
|
|
; CHECK: strcmp_expand_sub_join:
|
|
; CHECK-NEXT: [[TMP8:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP7]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP8]], 0
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%call = call i32 @strcmp(ptr %C, ptr @s1)
|
|
%cmp = icmp slt i32 %call, 0
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @expand_strcmp_sle_s1(ptr %C) {
|
|
; CHECK-LABEL: @expand_strcmp_sle_s1(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
|
|
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
|
|
; CHECK-NEXT: [[TMP3:%.*]] = sub nsw i32 [[TMP2]], 48
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
|
|
; CHECK-NEXT: br i1 [[TMP4]], label [[STRCMP_EXPAND_SUB_IS_ZERO:%.*]], label [[STRCMP_EXPAND_SUB_JOIN:%.*]]
|
|
; CHECK: strcmp_expand_sub_is_zero:
|
|
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
|
|
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
|
|
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
|
|
; CHECK-NEXT: br label [[STRCMP_EXPAND_SUB_JOIN]]
|
|
; CHECK: strcmp_expand_sub_join:
|
|
; CHECK-NEXT: [[TMP8:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP7]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP8]], 0
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%call = call i32 @strcmp(ptr %C, ptr @s1)
|
|
%cmp = icmp sle i32 %call, 0
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @expand_strcmp_s1_fail_1(ptr %C) {
|
|
; CHECK-LABEL: @expand_strcmp_s1_fail_1(
|
|
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr @s1)
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 1
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%call = call i32 @strcmp(ptr %C, ptr @s1)
|
|
%cmp = icmp eq i32 %call, 1
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @expand_strcmp_s1_fail_2(ptr %C) {
|
|
; CHECK-LABEL: @expand_strcmp_s1_fail_2(
|
|
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr @s1, ptr @s1)
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%call = call i32 @strcmp(ptr @s1, ptr @s1)
|
|
%cmp = icmp eq i32 %call, 0
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i32 @expand_strcmp_s1_fail_3(ptr %C) {
|
|
; CHECK-LABEL: @expand_strcmp_s1_fail_3(
|
|
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr @s1)
|
|
; CHECK-NEXT: ret i32 [[CALL]]
|
|
;
|
|
%call = call i32 @strcmp(ptr %C, ptr @s1)
|
|
ret i32 %call
|
|
}
|
|
|
|
define i1 @expand_strcmp_eq_s2(ptr %C) {
|
|
; CHECK-LABEL: @expand_strcmp_eq_s2(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
|
|
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
|
|
; CHECK-NEXT: [[TMP3:%.*]] = sub nsw i32 [[TMP2]], 48
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
|
|
; CHECK-NEXT: br i1 [[TMP4]], label [[STRCMP_EXPAND_SUB_IS_ZERO:%.*]], label [[STRCMP_EXPAND_SUB_JOIN:%.*]]
|
|
; CHECK: strcmp_expand_sub_is_zero:
|
|
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
|
|
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
|
|
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
|
|
; CHECK-NEXT: [[TMP8:%.*]] = sub nsw i32 [[TMP7]], 49
|
|
; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0
|
|
; CHECK-NEXT: br i1 [[TMP9]], label [[STRCMP_EXPAND_SUB_IS_ZERO1:%.*]], label [[STRCMP_EXPAND_SUB_JOIN]]
|
|
; CHECK: strcmp_expand_sub_is_zero1:
|
|
; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
|
|
; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
|
|
; CHECK-NEXT: [[TMP12:%.*]] = zext i8 [[TMP11]] to i32
|
|
; CHECK-NEXT: br label [[STRCMP_EXPAND_SUB_JOIN]]
|
|
; CHECK: strcmp_expand_sub_join:
|
|
; CHECK-NEXT: [[TMP13:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP8]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ], [ [[TMP12]], [[STRCMP_EXPAND_SUB_IS_ZERO1]] ]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP13]], 0
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%call = call i32 @strcmp(ptr %C, ptr @s2)
|
|
%cmp = icmp eq i32 %call, 0
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @expand_strcmp_ne_s2(ptr %C) {
|
|
; CHECK-LABEL: @expand_strcmp_ne_s2(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
|
|
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
|
|
; CHECK-NEXT: [[TMP3:%.*]] = sub nsw i32 [[TMP2]], 48
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
|
|
; CHECK-NEXT: br i1 [[TMP4]], label [[STRCMP_EXPAND_SUB_IS_ZERO:%.*]], label [[STRCMP_EXPAND_SUB_JOIN:%.*]]
|
|
; CHECK: strcmp_expand_sub_is_zero:
|
|
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
|
|
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
|
|
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
|
|
; CHECK-NEXT: [[TMP8:%.*]] = sub nsw i32 [[TMP7]], 49
|
|
; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0
|
|
; CHECK-NEXT: br i1 [[TMP9]], label [[STRCMP_EXPAND_SUB_IS_ZERO1:%.*]], label [[STRCMP_EXPAND_SUB_JOIN]]
|
|
; CHECK: strcmp_expand_sub_is_zero1:
|
|
; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
|
|
; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
|
|
; CHECK-NEXT: [[TMP12:%.*]] = zext i8 [[TMP11]] to i32
|
|
; CHECK-NEXT: br label [[STRCMP_EXPAND_SUB_JOIN]]
|
|
; CHECK: strcmp_expand_sub_join:
|
|
; CHECK-NEXT: [[TMP13:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP8]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ], [ [[TMP12]], [[STRCMP_EXPAND_SUB_IS_ZERO1]] ]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP13]], 0
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%call = call i32 @strcmp(ptr %C, ptr @s2)
|
|
%cmp = icmp ne i32 %call, 0
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @expand_strcmp_sgt_s2(ptr %C) {
|
|
; CHECK-LABEL: @expand_strcmp_sgt_s2(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
|
|
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
|
|
; CHECK-NEXT: [[TMP3:%.*]] = sub nsw i32 [[TMP2]], 48
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
|
|
; CHECK-NEXT: br i1 [[TMP4]], label [[STRCMP_EXPAND_SUB_IS_ZERO:%.*]], label [[STRCMP_EXPAND_SUB_JOIN:%.*]]
|
|
; CHECK: strcmp_expand_sub_is_zero:
|
|
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
|
|
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
|
|
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
|
|
; CHECK-NEXT: [[TMP8:%.*]] = sub nsw i32 [[TMP7]], 49
|
|
; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0
|
|
; CHECK-NEXT: br i1 [[TMP9]], label [[STRCMP_EXPAND_SUB_IS_ZERO1:%.*]], label [[STRCMP_EXPAND_SUB_JOIN]]
|
|
; CHECK: strcmp_expand_sub_is_zero1:
|
|
; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
|
|
; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
|
|
; CHECK-NEXT: [[TMP12:%.*]] = zext i8 [[TMP11]] to i32
|
|
; CHECK-NEXT: br label [[STRCMP_EXPAND_SUB_JOIN]]
|
|
; CHECK: strcmp_expand_sub_join:
|
|
; CHECK-NEXT: [[TMP13:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP8]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ], [ [[TMP12]], [[STRCMP_EXPAND_SUB_IS_ZERO1]] ]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP13]], 0
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%call = call i32 @strcmp(ptr %C, ptr @s2)
|
|
%cmp = icmp sgt i32 %call, 0
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @expand_strcmp_sge_s2(ptr %C) {
|
|
; CHECK-LABEL: @expand_strcmp_sge_s2(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
|
|
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
|
|
; CHECK-NEXT: [[TMP3:%.*]] = sub nsw i32 [[TMP2]], 48
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
|
|
; CHECK-NEXT: br i1 [[TMP4]], label [[STRCMP_EXPAND_SUB_IS_ZERO:%.*]], label [[STRCMP_EXPAND_SUB_JOIN:%.*]]
|
|
; CHECK: strcmp_expand_sub_is_zero:
|
|
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
|
|
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
|
|
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
|
|
; CHECK-NEXT: [[TMP8:%.*]] = sub nsw i32 [[TMP7]], 49
|
|
; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0
|
|
; CHECK-NEXT: br i1 [[TMP9]], label [[STRCMP_EXPAND_SUB_IS_ZERO1:%.*]], label [[STRCMP_EXPAND_SUB_JOIN]]
|
|
; CHECK: strcmp_expand_sub_is_zero1:
|
|
; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
|
|
; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
|
|
; CHECK-NEXT: [[TMP12:%.*]] = zext i8 [[TMP11]] to i32
|
|
; CHECK-NEXT: br label [[STRCMP_EXPAND_SUB_JOIN]]
|
|
; CHECK: strcmp_expand_sub_join:
|
|
; CHECK-NEXT: [[TMP13:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP8]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ], [ [[TMP12]], [[STRCMP_EXPAND_SUB_IS_ZERO1]] ]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[TMP13]], 0
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%call = call i32 @strcmp(ptr %C, ptr @s2)
|
|
%cmp = icmp sge i32 %call, 0
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @expand_strcmp_slt_s2(ptr %C) {
|
|
; CHECK-LABEL: @expand_strcmp_slt_s2(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
|
|
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
|
|
; CHECK-NEXT: [[TMP3:%.*]] = sub nsw i32 [[TMP2]], 48
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
|
|
; CHECK-NEXT: br i1 [[TMP4]], label [[STRCMP_EXPAND_SUB_IS_ZERO:%.*]], label [[STRCMP_EXPAND_SUB_JOIN:%.*]]
|
|
; CHECK: strcmp_expand_sub_is_zero:
|
|
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
|
|
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
|
|
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
|
|
; CHECK-NEXT: [[TMP8:%.*]] = sub nsw i32 [[TMP7]], 49
|
|
; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0
|
|
; CHECK-NEXT: br i1 [[TMP9]], label [[STRCMP_EXPAND_SUB_IS_ZERO1:%.*]], label [[STRCMP_EXPAND_SUB_JOIN]]
|
|
; CHECK: strcmp_expand_sub_is_zero1:
|
|
; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
|
|
; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
|
|
; CHECK-NEXT: [[TMP12:%.*]] = zext i8 [[TMP11]] to i32
|
|
; CHECK-NEXT: br label [[STRCMP_EXPAND_SUB_JOIN]]
|
|
; CHECK: strcmp_expand_sub_join:
|
|
; CHECK-NEXT: [[TMP13:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP8]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ], [ [[TMP12]], [[STRCMP_EXPAND_SUB_IS_ZERO1]] ]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP13]], 0
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%call = call i32 @strcmp(ptr %C, ptr @s2)
|
|
%cmp = icmp slt i32 %call, 0
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @expand_strcmp_sle_s2(ptr %C) {
|
|
; CHECK-LABEL: @expand_strcmp_sle_s2(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr [[C:%.*]], align 1
|
|
; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32
|
|
; CHECK-NEXT: [[TMP3:%.*]] = sub nsw i32 [[TMP2]], 48
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 0
|
|
; CHECK-NEXT: br i1 [[TMP4]], label [[STRCMP_EXPAND_SUB_IS_ZERO:%.*]], label [[STRCMP_EXPAND_SUB_JOIN:%.*]]
|
|
; CHECK: strcmp_expand_sub_is_zero:
|
|
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 1
|
|
; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1
|
|
; CHECK-NEXT: [[TMP7:%.*]] = zext i8 [[TMP6]] to i32
|
|
; CHECK-NEXT: [[TMP8:%.*]] = sub nsw i32 [[TMP7]], 49
|
|
; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0
|
|
; CHECK-NEXT: br i1 [[TMP9]], label [[STRCMP_EXPAND_SUB_IS_ZERO1:%.*]], label [[STRCMP_EXPAND_SUB_JOIN]]
|
|
; CHECK: strcmp_expand_sub_is_zero1:
|
|
; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i8, ptr [[C]], i64 2
|
|
; CHECK-NEXT: [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
|
|
; CHECK-NEXT: [[TMP12:%.*]] = zext i8 [[TMP11]] to i32
|
|
; CHECK-NEXT: br label [[STRCMP_EXPAND_SUB_JOIN]]
|
|
; CHECK: strcmp_expand_sub_join:
|
|
; CHECK-NEXT: [[TMP13:%.*]] = phi i32 [ [[TMP3]], [[TMP0:%.*]] ], [ [[TMP8]], [[STRCMP_EXPAND_SUB_IS_ZERO]] ], [ [[TMP12]], [[STRCMP_EXPAND_SUB_IS_ZERO1]] ]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP13]], 0
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%call = call i32 @strcmp(ptr %C, ptr @s2)
|
|
%cmp = icmp sle i32 %call, 0
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @expand_strcmp_s3(ptr %C) {
|
|
; CHECK-LABEL: @expand_strcmp_s3(
|
|
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr @s3)
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%call = call i32 @strcmp(ptr %C, ptr @s3)
|
|
%cmp = icmp eq i32 %call, 0
|
|
ret i1 %cmp
|
|
}
|
|
|
|
define i1 @expand_strcmp_s4(ptr %C) {
|
|
; CHECK-LABEL: @expand_strcmp_s4(
|
|
; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr @s4)
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%call = call i32 @strcmp(ptr %C, ptr @s4)
|
|
%cmp = icmp eq i32 %call, 0
|
|
ret i1 %cmp
|
|
}
|