diff options
-rw-r--r-- | llvm/test/Transforms/InstCombine/widenable-conditions.ll | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/llvm/test/Transforms/InstCombine/widenable-conditions.ll b/llvm/test/Transforms/InstCombine/widenable-conditions.ll new file mode 100644 index 00000000000..4f36647241f --- /dev/null +++ b/llvm/test/Transforms/InstCombine/widenable-conditions.ll @@ -0,0 +1,156 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -instcombine -S | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define i1 @test1(i1 %a, i1 %b) { +; CHECK-LABEL: @test1( +; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: [[LHS:%.*]] = and i1 [[WC]], [[B:%.*]] +; CHECK-NEXT: [[AND:%.*]] = and i1 [[LHS]], [[A:%.*]] +; CHECK-NEXT: ret i1 [[AND]] +; + %wc = call i1 @llvm.experimental.widenable.condition() + %lhs = and i1 %b, %wc + %and = and i1 %lhs, %a + ret i1 %and +} + +; Negative test - profitability of dropping WC from first use unclear +define i1 @test1b(i1 %a, i1 %b) { +; CHECK-LABEL: @test1b( +; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: [[LHS:%.*]] = and i1 [[WC]], [[B:%.*]] +; CHECK-NEXT: call void @use(i1 [[LHS]]) +; CHECK-NEXT: [[AND:%.*]] = and i1 [[LHS]], [[A:%.*]] +; CHECK-NEXT: ret i1 [[AND]] +; + %wc = call i1 @llvm.experimental.widenable.condition() + %lhs = and i1 %b, %wc + call void @use(i1 %lhs) + %and = and i1 %lhs, %a + ret i1 %and +} + +; multiple uses of A, B, WC doesn't change result +define i1 @test1c(i1 %a, i1 %b) { +; CHECK-LABEL: @test1c( +; CHECK-NEXT: call void @use(i1 [[A:%.*]]) +; CHECK-NEXT: call void @use(i1 [[B:%.*]]) +; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: call void @use(i1 [[WC]]) +; CHECK-NEXT: [[LHS:%.*]] = and i1 [[WC]], [[B]] +; CHECK-NEXT: [[AND:%.*]] = and i1 [[LHS]], [[A]] +; CHECK-NEXT: ret i1 [[AND]] +; + call void @use(i1 %a) + call void @use(i1 %b) + %wc = call i1 @llvm.experimental.widenable.condition() + call void @use(i1 %wc) + %lhs = and i1 %b, %wc + %and = and i1 %lhs, %a + ret i1 %and +} + +define i1 @test2(i1 %a, i1 %b) { +; CHECK-LABEL: @test2( +; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: [[LHS:%.*]] = and i1 [[WC]], [[B:%.*]] +; CHECK-NEXT: [[AND:%.*]] = and i1 [[LHS]], [[A:%.*]] +; CHECK-NEXT: ret i1 [[AND]] +; + %wc = call i1 @llvm.experimental.widenable.condition() + %lhs = and i1 %wc, %b + %and = and i1 %lhs, %a + ret i1 %and +} + +; To test the rhs side, an instruction on lhs to prevent complexity +; canonicalization reducing to above. +define i1 @test3(i1 %a, i1 %b, i1 %c) { +; CHECK-LABEL: @test3( +; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: [[LHS:%.*]] = and i1 [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: [[RHS:%.*]] = and i1 [[WC]], [[C:%.*]] +; CHECK-NEXT: [[AND:%.*]] = and i1 [[LHS]], [[RHS]] +; CHECK-NEXT: ret i1 [[AND]] +; + %wc = call i1 @llvm.experimental.widenable.condition() + %lhs = and i1 %a, %b + %rhs = and i1 %c, %wc + %and = and i1 %lhs, %rhs + ret i1 %and +} + +define i1 @test4(i1 %a, i1 %b, i1 %c) { +; CHECK-LABEL: @test4( +; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: [[LHS:%.*]] = and i1 [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: [[RHS:%.*]] = and i1 [[WC]], [[C:%.*]] +; CHECK-NEXT: [[AND:%.*]] = and i1 [[LHS]], [[RHS]] +; CHECK-NEXT: ret i1 [[AND]] +; + %wc = call i1 @llvm.experimental.widenable.condition() + %lhs = and i1 %a, %b + %rhs = and i1 %wc, %c + %and = and i1 %lhs, %rhs + ret i1 %and +} + +define i1 @test5(i1 %a, i1 %b) { +; CHECK-LABEL: @test5( +; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: ret i1 [[WC]] +; + %wc = call i1 @llvm.experimental.widenable.condition() + %and = and i1 %wc, %wc + ret i1 %and +} + +define i1 @test6(i1 %a, i1 %b) { +; CHECK-LABEL: @test6( +; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: [[AND:%.*]] = and i1 [[WC]], [[WC2]] +; CHECK-NEXT: ret i1 [[AND]] +; + %wc = call i1 @llvm.experimental.widenable.condition() + %wc2 = call i1 @llvm.experimental.widenable.condition() + %and = and i1 %wc, %wc2 + ret i1 %and +} + +define i1 @test7(i1 %a, i1 %b) { +; CHECK-LABEL: @test7( +; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: call void @use(i1 [[WC]]) +; CHECK-NEXT: [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: [[AND:%.*]] = and i1 [[WC]], [[WC2]] +; CHECK-NEXT: ret i1 [[AND]] +; + %wc = call i1 @llvm.experimental.widenable.condition() + call void @use(i1 %wc) + %wc2 = call i1 @llvm.experimental.widenable.condition() + %and = and i1 %wc, %wc2 + ret i1 %and +} + +define i1 @test8(i1 %a, i1 %b) { +; CHECK-LABEL: @test8( +; CHECK-NEXT: [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: call void @use(i1 [[WC2]]) +; CHECK-NEXT: [[AND:%.*]] = and i1 [[WC]], [[WC2]] +; CHECK-NEXT: ret i1 [[AND]] +; + %wc = call i1 @llvm.experimental.widenable.condition() + %wc2 = call i1 @llvm.experimental.widenable.condition() + call void @use(i1 %wc2) + %and = and i1 %wc, %wc2 + ret i1 %and +} + + +declare void @use(i1) +declare i1 @llvm.experimental.widenable.condition() |