Index: llvm/test/Transforms/AggressiveInstCombine/strcmp.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/AggressiveInstCombine/strcmp.ll @@ -0,0 +1,219 @@ +; 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"). + +define i1 @expand_strcmp_s0(ptr %C) { +; CHECK-LABEL: @expand_strcmp_s0( +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr noundef @s0) +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0 +; CHECK-NEXT: ret i1 [[CMP]] +; + %call = call i32 @strcmp(ptr %C, ptr noundef @s0) + %cmp = icmp eq i32 %call, 0 + ret i1 %cmp +} + +define i1 @expand_strcmp_s1_1(ptr %C) { +; CHECK-LABEL: @expand_strcmp_s1_1( +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr noundef @s1) +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0 +; CHECK-NEXT: ret i1 [[CMP]] +; + %call = call i32 @strcmp(ptr %C, ptr noundef @s1) + %cmp = icmp eq i32 %call, 0 + ret i1 %cmp +} + +define i1 @expand_strcmp_s1_2(ptr %C) { +; CHECK-LABEL: @expand_strcmp_s1_2( +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr noundef @s1, ptr [[C:%.*]]) +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0 +; CHECK-NEXT: ret i1 [[CMP]] +; + %call = call i32 @strcmp(ptr noundef @s1, ptr %C) + %cmp = icmp eq i32 %call, 0 + ret i1 %cmp +} + +define i1 @expand_strcmp_s1_3(ptr %C) { +; CHECK-LABEL: @expand_strcmp_s1_3( +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr noundef @s1) +; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[CALL]], 0 +; CHECK-NEXT: ret i1 [[CMP]] +; + %call = call i32 @strcmp(ptr %C, ptr noundef @s1) + %cmp = icmp ne i32 %call, 0 + ret i1 %cmp +} + +define i1 @expand_strcmp_s1_4(ptr %C) { +; CHECK-LABEL: @expand_strcmp_s1_4( +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr noundef @s1, ptr [[C:%.*]]) +; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[CALL]], 0 +; CHECK-NEXT: ret i1 [[CMP]] +; + %call = call i32 @strcmp(ptr noundef @s1, ptr %C) + %cmp = icmp ne i32 %call, 0 + ret i1 %cmp +} + +define i1 @expand_strcmp_s1_5(ptr %C) { +; CHECK-LABEL: @expand_strcmp_s1_5( +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr noundef @s1) +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CALL]], 0 +; CHECK-NEXT: ret i1 [[CMP]] +; + %call = call i32 @strcmp(ptr %C, ptr noundef @s1) + %cmp = icmp sgt i32 %call, 0 + ret i1 %cmp +} + +define i1 @expand_strcmp_s1_6(ptr %C) { +; CHECK-LABEL: @expand_strcmp_s1_6( +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr noundef @s1, ptr [[C:%.*]]) +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CALL]], 0 +; CHECK-NEXT: ret i1 [[CMP]] +; + %call = call i32 @strcmp(ptr noundef @s1, ptr %C) + %cmp = icmp sgt i32 %call, 0 + ret i1 %cmp +} + +define i1 @expand_strcmp_s1_7(ptr %C) { +; CHECK-LABEL: @expand_strcmp_s1_7( +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr noundef @s1) +; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[CALL]], 0 +; CHECK-NEXT: ret i1 [[CMP]] +; + %call = call i32 @strcmp(ptr %C, ptr noundef @s1) + %cmp = icmp sge i32 %call, 0 + ret i1 %cmp +} + +define i1 @expand_strcmp_s1_8(ptr %C) { +; CHECK-LABEL: @expand_strcmp_s1_8( +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr noundef @s1, ptr [[C:%.*]]) +; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[CALL]], 0 +; CHECK-NEXT: ret i1 [[CMP]] +; + %call = call i32 @strcmp(ptr noundef @s1, ptr %C) + %cmp = icmp sge i32 %call, 0 + ret i1 %cmp +} + +define i1 @expand_strcmp_s1_9(ptr %C) { +; CHECK-LABEL: @expand_strcmp_s1_9( +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr noundef @s1) +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[CALL]], 0 +; CHECK-NEXT: ret i1 [[CMP]] +; + %call = call i32 @strcmp(ptr %C, ptr noundef @s1) + %cmp = icmp slt i32 %call, 0 + ret i1 %cmp +} + +define i1 @expand_strcmp_s1_10(ptr %C) { +; CHECK-LABEL: @expand_strcmp_s1_10( +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr noundef @s1, ptr [[C:%.*]]) +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[CALL]], 0 +; CHECK-NEXT: ret i1 [[CMP]] +; + %call = call i32 @strcmp(ptr noundef @s1, ptr %C) + %cmp = icmp slt i32 %call, 0 + ret i1 %cmp +} + +define i1 @expand_strcmp_s1_11(ptr %C) { +; CHECK-LABEL: @expand_strcmp_s1_11( +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr noundef @s1) +; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[CALL]], 0 +; CHECK-NEXT: ret i1 [[CMP]] +; + %call = call i32 @strcmp(ptr %C, ptr noundef @s1) + %cmp = icmp sle i32 %call, 0 + ret i1 %cmp +} + +define i1 @expand_strcmp_s1_12(ptr %C) { +; CHECK-LABEL: @expand_strcmp_s1_12( +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr noundef @s1, ptr [[C:%.*]]) +; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[CALL]], 0 +; CHECK-NEXT: ret i1 [[CMP]] +; + %call = call i32 @strcmp(ptr noundef @s1, ptr %C) + %cmp = icmp sle i32 %call, 0 + ret i1 %cmp +} + +define i1 @expand_strcmp_s1_13(ptr %C) { +; CHECK-LABEL: @expand_strcmp_s1_13( +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr noundef @s1) +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 1 +; CHECK-NEXT: ret i1 [[CMP]] +; + %call = call i32 @strcmp(ptr %C, ptr noundef @s1) + %cmp = icmp eq i32 %call, 1 + ret i1 %cmp +} + +define i1 @expand_strcmp_s1_14(ptr %C) { +; CHECK-LABEL: @expand_strcmp_s1_14( +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr noundef @s1, ptr noundef @s1) +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0 +; CHECK-NEXT: ret i1 [[CMP]] +; + %call = call i32 @strcmp(ptr noundef @s1, ptr noundef @s1) + %cmp = icmp eq i32 %call, 0 + ret i1 %cmp +} + +define i32 @expand_strcmp_s1_15(ptr %C) { +; CHECK-LABEL: @expand_strcmp_s1_15( +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr noundef @s1) +; CHECK-NEXT: ret i32 [[CALL]] +; + %call = call i32 @strcmp(ptr %C, ptr noundef @s1) + ret i32 %call +} + +define i1 @expand_strcmp_s2(ptr %C) { +; CHECK-LABEL: @expand_strcmp_s2( +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strcmp(ptr [[C:%.*]], ptr noundef @s2) +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0 +; CHECK-NEXT: ret i1 [[CMP]] +; + %call = call i32 @strcmp(ptr %C, ptr noundef @s2) + %cmp = icmp eq 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 noundef @s3) +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0 +; CHECK-NEXT: ret i1 [[CMP]] +; + %call = call i32 @strcmp(ptr %C, ptr noundef @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 noundef @s4) +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0 +; CHECK-NEXT: ret i1 [[CMP]] +; + %call = call i32 @strcmp(ptr %C, ptr noundef @s4) + %cmp = icmp eq i32 %call, 0 + ret i1 %cmp +}