[llvm] 20bbd88 - [SimplifyCFG] Cost speculated selects with their real scalar condition (#217664)

via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 27 10:41:19 PDT 2026


Author: Guy David
Date: 2026-09-27T20:41:13+03:00
New Revision: 20bbd88cf9e7be286b25c29c877c2d0564da9ecf

URL: https://github.com/llvm/llvm-project/commit/20bbd88cf9e7be286b25c29c877c2d0564da9ecf
DIFF: https://github.com/llvm/llvm-project/commit/20bbd88cf9e7be286b25c29c877c2d0564da9ecf.diff

LOG: [SimplifyCFG] Cost speculated selects with their real scalar condition (#217664)

`validateAndCostRequiredSelects()` priced the selects that
`speculativelyExecuteBB()` would create using
`CmpInst::makeCmpResultType(PN->getType())` as the condition type. For a
vector phi, that asks the target for the cost of a per-lane vector
select, but the select actually created uses the branch condition, which
is always a scalar `i1`.

This only changes behaviour where a target's cost model distinguishes
the two condition types. Of the targets checked, only AArch64 does.

This may worsen the compiler's output in RISC-V, X86, ARM, so no
intention to merge soon before collecting more feedback on how the
different targets should communicate this property.

Added: 
    llvm/test/Transforms/SimplifyCFG/AArch64/speculate-vector-phi-select-cost.ll
    llvm/test/Transforms/SimplifyCFG/ARM/speculate-vector-phi-select-cost.ll
    llvm/test/Transforms/SimplifyCFG/RISCV/speculate-mask-phi-select-cost.ll
    llvm/test/Transforms/SimplifyCFG/X86/speculate-mask-phi-select-cost.ll

Modified: 
    llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 7134ab2a7f40c..9771b04c418f5 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -3149,7 +3149,7 @@ static bool validateAndCostRequiredSelects(BasicBlock *BB, BasicBlock *ThenBB,
       continue;
 
     Cost += TTI.getCmpSelInstrCost(Instruction::Select, PN.getType(),
-                                   CmpInst::makeCmpResultType(PN.getType()),
+                                   Type::getInt1Ty(PN.getContext()),
                                    CmpInst::BAD_ICMP_PREDICATE, CostKind);
 
     // Don't convert to selects if we could remove undefined behavior instead.

diff  --git a/llvm/test/Transforms/SimplifyCFG/AArch64/speculate-vector-phi-select-cost.ll b/llvm/test/Transforms/SimplifyCFG/AArch64/speculate-vector-phi-select-cost.ll
new file mode 100644
index 0000000000000..11a98c24f95c2
--- /dev/null
+++ b/llvm/test/Transforms/SimplifyCFG/AArch64/speculate-vector-phi-select-cost.ll
@@ -0,0 +1,90 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -mtriple=aarch64-unknown-linux-gnu -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S < %s | FileCheck %s
+
+define <2 x double> @speculate_v2f64(i32 %n, <2 x double> %a, <2 x double> %b, i1 %other) {
+; CHECK-LABEL: define <2 x double> @speculate_v2f64(
+; CHECK-SAME: i32 [[N:%.*]], <2 x double> [[A:%.*]], <2 x double> [[B:%.*]], i1 [[OTHER:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br i1 [[OTHER]], label %[[MERGE:.*]], label %[[GUARDED:.*]]
+; CHECK:       [[GUARDED]]:
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[N]], 0
+; CHECK-NEXT:    br i1 [[CMP]], label %[[THEN:.*]], label %[[MERGE]]
+; CHECK:       [[THEN]]:
+; CHECK-NEXT:    [[SCALED:%.*]] = fadd <2 x double> [[A]], [[B]]
+; CHECK-NEXT:    br label %[[MERGE]]
+; CHECK:       [[MERGE]]:
+; CHECK-NEXT:    [[R:%.*]] = phi <2 x double> [ zeroinitializer, %[[ENTRY]] ], [ [[SCALED]], %[[THEN]] ], [ [[B]], %[[GUARDED]] ]
+; CHECK-NEXT:    ret <2 x double> [[R]]
+;
+entry:
+  br i1 %other, label %merge, label %guarded
+
+guarded:
+  %cmp = icmp sgt i32 %n, 0
+  br i1 %cmp, label %then, label %merge
+
+then:
+  %scaled = fadd <2 x double> %a, %b
+  br label %merge
+
+merge:
+  %r = phi <2 x double> [ zeroinitializer, %entry ], [ %scaled, %then ], [ %b, %guarded ]
+  ret <2 x double> %r
+}
+
+define <4 x double> @speculate_v4f64(i32 %n, <4 x double> %a, <4 x double> %b, i1 %other) {
+; CHECK-LABEL: define <4 x double> @speculate_v4f64(
+; CHECK-SAME: i32 [[N:%.*]], <4 x double> [[A:%.*]], <4 x double> [[B:%.*]], i1 [[OTHER:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br i1 [[OTHER]], label %[[MERGE:.*]], label %[[GUARDED:.*]]
+; CHECK:       [[GUARDED]]:
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[N]], 0
+; CHECK-NEXT:    br i1 [[CMP]], label %[[THEN:.*]], label %[[MERGE]]
+; CHECK:       [[THEN]]:
+; CHECK-NEXT:    [[SCALED:%.*]] = fadd <4 x double> [[A]], [[B]]
+; CHECK-NEXT:    br label %[[MERGE]]
+; CHECK:       [[MERGE]]:
+; CHECK-NEXT:    [[R:%.*]] = phi <4 x double> [ zeroinitializer, %[[ENTRY]] ], [ [[SCALED]], %[[THEN]] ], [ [[B]], %[[GUARDED]] ]
+; CHECK-NEXT:    ret <4 x double> [[R]]
+;
+entry:
+  br i1 %other, label %merge, label %guarded
+
+guarded:
+  %cmp = icmp sgt i32 %n, 0
+  br i1 %cmp, label %then, label %merge
+
+then:
+  %scaled = fadd <4 x double> %a, %b
+  br label %merge
+
+merge:
+  %r = phi <4 x double> [ zeroinitializer, %entry ], [ %scaled, %then ], [ %b, %guarded ]
+  ret <4 x double> %r
+}
+
+define double @speculate_f64(i32 %n, double %a, double %b, i1 %other) {
+; CHECK-LABEL: define double @speculate_f64(
+; CHECK-SAME: i32 [[N:%.*]], double [[A:%.*]], double [[B:%.*]], i1 [[OTHER:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[N]], 0
+; CHECK-NEXT:    [[SCALED:%.*]] = fadd double [[A]], [[B]]
+; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[CMP]], double [[SCALED]], double [[B]]
+; CHECK-NEXT:    [[R:%.*]] = select i1 [[OTHER]], double 0.000000e+00, double [[SPEC_SELECT]]
+; CHECK-NEXT:    ret double [[R]]
+;
+entry:
+  br i1 %other, label %merge, label %guarded
+
+guarded:
+  %cmp = icmp sgt i32 %n, 0
+  br i1 %cmp, label %then, label %merge
+
+then:
+  %scaled = fadd double %a, %b
+  br label %merge
+
+merge:
+  %r = phi double [ 0.0, %entry ], [ %scaled, %then ], [ %b, %guarded ]
+  ret double %r
+}

diff  --git a/llvm/test/Transforms/SimplifyCFG/ARM/speculate-vector-phi-select-cost.ll b/llvm/test/Transforms/SimplifyCFG/ARM/speculate-vector-phi-select-cost.ll
new file mode 100644
index 0000000000000..56b51398a51fe
--- /dev/null
+++ b/llvm/test/Transforms/SimplifyCFG/ARM/speculate-vector-phi-select-cost.ll
@@ -0,0 +1,90 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -mtriple=thumbv8.1m.main -mattr=+mve.fp -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S < %s | FileCheck %s
+
+define <4 x float> @speculate_v4f32(i32 %n, <4 x float> %a, <4 x float> %b, i1 %other) {
+; CHECK-LABEL: define <4 x float> @speculate_v4f32(
+; CHECK-SAME: i32 [[N:%.*]], <4 x float> [[A:%.*]], <4 x float> [[B:%.*]], i1 [[OTHER:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br i1 [[OTHER]], label %[[MERGE:.*]], label %[[GUARDED:.*]]
+; CHECK:       [[GUARDED]]:
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[N]], 0
+; CHECK-NEXT:    br i1 [[CMP]], label %[[THEN:.*]], label %[[MERGE]]
+; CHECK:       [[THEN]]:
+; CHECK-NEXT:    [[ADD:%.*]] = fadd <4 x float> [[A]], [[B]]
+; CHECK-NEXT:    br label %[[MERGE]]
+; CHECK:       [[MERGE]]:
+; CHECK-NEXT:    [[R:%.*]] = phi <4 x float> [ zeroinitializer, %[[ENTRY]] ], [ [[ADD]], %[[THEN]] ], [ [[B]], %[[GUARDED]] ]
+; CHECK-NEXT:    ret <4 x float> [[R]]
+;
+entry:
+  br i1 %other, label %merge, label %guarded
+
+guarded:
+  %cmp = icmp sgt i32 %n, 0
+  br i1 %cmp, label %then, label %merge
+
+then:
+  %add = fadd <4 x float> %a, %b
+  br label %merge
+
+merge:
+  %r = phi <4 x float> [ zeroinitializer, %entry ], [ %add, %then ], [ %b, %guarded ]
+  ret <4 x float> %r
+}
+
+define <8 x half> @speculate_v8f16(i32 %n, <8 x half> %a, <8 x half> %b, i1 %other) {
+; CHECK-LABEL: define <8 x half> @speculate_v8f16(
+; CHECK-SAME: i32 [[N:%.*]], <8 x half> [[A:%.*]], <8 x half> [[B:%.*]], i1 [[OTHER:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br i1 [[OTHER]], label %[[MERGE:.*]], label %[[GUARDED:.*]]
+; CHECK:       [[GUARDED]]:
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[N]], 0
+; CHECK-NEXT:    br i1 [[CMP]], label %[[THEN:.*]], label %[[MERGE]]
+; CHECK:       [[THEN]]:
+; CHECK-NEXT:    [[ADD:%.*]] = fadd <8 x half> [[A]], [[B]]
+; CHECK-NEXT:    br label %[[MERGE]]
+; CHECK:       [[MERGE]]:
+; CHECK-NEXT:    [[R:%.*]] = phi <8 x half> [ zeroinitializer, %[[ENTRY]] ], [ [[ADD]], %[[THEN]] ], [ [[B]], %[[GUARDED]] ]
+; CHECK-NEXT:    ret <8 x half> [[R]]
+;
+entry:
+  br i1 %other, label %merge, label %guarded
+
+guarded:
+  %cmp = icmp sgt i32 %n, 0
+  br i1 %cmp, label %then, label %merge
+
+then:
+  %add = fadd <8 x half> %a, %b
+  br label %merge
+
+merge:
+  %r = phi <8 x half> [ zeroinitializer, %entry ], [ %add, %then ], [ %b, %guarded ]
+  ret <8 x half> %r
+}
+
+define float @speculate_f32(i32 %n, float %a, float %b, i1 %other) {
+; CHECK-LABEL: define float @speculate_f32(
+; CHECK-SAME: i32 [[N:%.*]], float [[A:%.*]], float [[B:%.*]], i1 [[OTHER:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[N]], 0
+; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[A]], [[B]]
+; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[CMP]], float [[ADD]], float [[B]]
+; CHECK-NEXT:    [[R:%.*]] = select i1 [[OTHER]], float 0.000000e+00, float [[SPEC_SELECT]]
+; CHECK-NEXT:    ret float [[R]]
+;
+entry:
+  br i1 %other, label %merge, label %guarded
+
+guarded:
+  %cmp = icmp sgt i32 %n, 0
+  br i1 %cmp, label %then, label %merge
+
+then:
+  %add = fadd float %a, %b
+  br label %merge
+
+merge:
+  %r = phi float [ 0.0, %entry ], [ %add, %then ], [ %b, %guarded ]
+  ret float %r
+}

diff  --git a/llvm/test/Transforms/SimplifyCFG/RISCV/speculate-mask-phi-select-cost.ll b/llvm/test/Transforms/SimplifyCFG/RISCV/speculate-mask-phi-select-cost.ll
new file mode 100644
index 0000000000000..746b0b472fb2c
--- /dev/null
+++ b/llvm/test/Transforms/SimplifyCFG/RISCV/speculate-mask-phi-select-cost.ll
@@ -0,0 +1,80 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -mtriple=riscv64 -mattr=+v -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S < %s | FileCheck %s
+
+define <4 x i1> @speculate_v4i1(i32 %n, <4 x i1> %a, <4 x i1> %b, i1 %other) {
+; CHECK-LABEL: define <4 x i1> @speculate_v4i1(
+; CHECK-SAME: i32 [[N:%.*]], <4 x i1> [[A:%.*]], <4 x i1> [[B:%.*]], i1 [[OTHER:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:  [[GUARDED:.*:]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[N]], 0
+; CHECK-NEXT:    [[AND:%.*]] = and <4 x i1> [[A]], [[B]]
+; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[CMP]], <4 x i1> [[AND]], <4 x i1> [[B]]
+; CHECK-NEXT:    [[R:%.*]] = select i1 [[OTHER]], <4 x i1> zeroinitializer, <4 x i1> [[SPEC_SELECT]]
+; CHECK-NEXT:    ret <4 x i1> [[R]]
+;
+entry:
+  br i1 %other, label %merge, label %guarded
+
+guarded:
+  %cmp = icmp sgt i32 %n, 0
+  br i1 %cmp, label %then, label %merge
+
+then:
+  %and = and <4 x i1> %a, %b
+  br label %merge
+
+merge:
+  %r = phi <4 x i1> [ zeroinitializer, %entry ], [ %and, %then ], [ %b, %guarded ]
+  ret <4 x i1> %r
+}
+
+define <8 x i1> @speculate_v8i1(i32 %n, <8 x i1> %a, <8 x i1> %b, i1 %other) {
+; CHECK-LABEL: define <8 x i1> @speculate_v8i1(
+; CHECK-SAME: i32 [[N:%.*]], <8 x i1> [[A:%.*]], <8 x i1> [[B:%.*]], i1 [[OTHER:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:  [[GUARDED:.*:]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[N]], 0
+; CHECK-NEXT:    [[AND:%.*]] = and <8 x i1> [[A]], [[B]]
+; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[CMP]], <8 x i1> [[AND]], <8 x i1> [[B]]
+; CHECK-NEXT:    [[R:%.*]] = select i1 [[OTHER]], <8 x i1> zeroinitializer, <8 x i1> [[SPEC_SELECT]]
+; CHECK-NEXT:    ret <8 x i1> [[R]]
+;
+entry:
+  br i1 %other, label %merge, label %guarded
+
+guarded:
+  %cmp = icmp sgt i32 %n, 0
+  br i1 %cmp, label %then, label %merge
+
+then:
+  %and = and <8 x i1> %a, %b
+  br label %merge
+
+merge:
+  %r = phi <8 x i1> [ zeroinitializer, %entry ], [ %and, %then ], [ %b, %guarded ]
+  ret <8 x i1> %r
+}
+
+define <4 x float> @speculate_v4f32(i32 %n, <4 x float> %a, <4 x float> %b, i1 %other) {
+; CHECK-LABEL: define <4 x float> @speculate_v4f32(
+; CHECK-SAME: i32 [[N:%.*]], <4 x float> [[A:%.*]], <4 x float> [[B:%.*]], i1 [[OTHER:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[N]], 0
+; CHECK-NEXT:    [[ADD:%.*]] = fadd <4 x float> [[A]], [[B]]
+; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[CMP]], <4 x float> [[ADD]], <4 x float> [[B]]
+; CHECK-NEXT:    [[R:%.*]] = select i1 [[OTHER]], <4 x float> zeroinitializer, <4 x float> [[SPEC_SELECT]]
+; CHECK-NEXT:    ret <4 x float> [[R]]
+;
+entry:
+  br i1 %other, label %merge, label %guarded
+
+guarded:
+  %cmp = icmp sgt i32 %n, 0
+  br i1 %cmp, label %then, label %merge
+
+then:
+  %add = fadd <4 x float> %a, %b
+  br label %merge
+
+merge:
+  %r = phi <4 x float> [ zeroinitializer, %entry ], [ %add, %then ], [ %b, %guarded ]
+  ret <4 x float> %r
+}

diff  --git a/llvm/test/Transforms/SimplifyCFG/X86/speculate-mask-phi-select-cost.ll b/llvm/test/Transforms/SimplifyCFG/X86/speculate-mask-phi-select-cost.ll
new file mode 100644
index 0000000000000..f7e2f5943a390
--- /dev/null
+++ b/llvm/test/Transforms/SimplifyCFG/X86/speculate-mask-phi-select-cost.ll
@@ -0,0 +1,106 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -mtriple=x86_64-unknown-linux-gnu -mattr=+avx512f,+avx512bw,+avx512vl -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S < %s | FileCheck %s
+
+define <8 x i1> @speculate_v8i1(i32 %n, <8 x i1> %a, <8 x i1> %b, i1 %other) {
+; CHECK-LABEL: define <8 x i1> @speculate_v8i1(
+; CHECK-SAME: i32 [[N:%.*]], <8 x i1> [[A:%.*]], <8 x i1> [[B:%.*]], i1 [[OTHER:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:  [[GUARDED:.*:]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[N]], 0
+; CHECK-NEXT:    [[AND:%.*]] = and <8 x i1> [[A]], [[B]]
+; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[CMP]], <8 x i1> [[AND]], <8 x i1> [[B]]
+; CHECK-NEXT:    [[R:%.*]] = select i1 [[OTHER]], <8 x i1> zeroinitializer, <8 x i1> [[SPEC_SELECT]]
+; CHECK-NEXT:    ret <8 x i1> [[R]]
+;
+entry:
+  br i1 %other, label %merge, label %guarded
+
+guarded:
+  %cmp = icmp sgt i32 %n, 0
+  br i1 %cmp, label %then, label %merge
+
+then:
+  %and = and <8 x i1> %a, %b
+  br label %merge
+
+merge:
+  %r = phi <8 x i1> [ zeroinitializer, %entry ], [ %and, %then ], [ %b, %guarded ]
+  ret <8 x i1> %r
+}
+
+define <16 x i1> @speculate_v16i1(i32 %n, <16 x i1> %a, <16 x i1> %b, i1 %other) {
+; CHECK-LABEL: define <16 x i1> @speculate_v16i1(
+; CHECK-SAME: i32 [[N:%.*]], <16 x i1> [[A:%.*]], <16 x i1> [[B:%.*]], i1 [[OTHER:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:  [[GUARDED:.*:]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[N]], 0
+; CHECK-NEXT:    [[AND:%.*]] = and <16 x i1> [[A]], [[B]]
+; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[CMP]], <16 x i1> [[AND]], <16 x i1> [[B]]
+; CHECK-NEXT:    [[R:%.*]] = select i1 [[OTHER]], <16 x i1> zeroinitializer, <16 x i1> [[SPEC_SELECT]]
+; CHECK-NEXT:    ret <16 x i1> [[R]]
+;
+entry:
+  br i1 %other, label %merge, label %guarded
+
+guarded:
+  %cmp = icmp sgt i32 %n, 0
+  br i1 %cmp, label %then, label %merge
+
+then:
+  %and = and <16 x i1> %a, %b
+  br label %merge
+
+merge:
+  %r = phi <16 x i1> [ zeroinitializer, %entry ], [ %and, %then ], [ %b, %guarded ]
+  ret <16 x i1> %r
+}
+
+define <4 x float> @speculate_v4f32(i32 %n, <4 x float> %a, <4 x float> %b, i1 %other) {
+; CHECK-LABEL: define <4 x float> @speculate_v4f32(
+; CHECK-SAME: i32 [[N:%.*]], <4 x float> [[A:%.*]], <4 x float> [[B:%.*]], i1 [[OTHER:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[N]], 0
+; CHECK-NEXT:    [[ADD:%.*]] = fadd <4 x float> [[A]], [[B]]
+; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[CMP]], <4 x float> [[ADD]], <4 x float> [[B]]
+; CHECK-NEXT:    [[R:%.*]] = select i1 [[OTHER]], <4 x float> zeroinitializer, <4 x float> [[SPEC_SELECT]]
+; CHECK-NEXT:    ret <4 x float> [[R]]
+;
+entry:
+  br i1 %other, label %merge, label %guarded
+
+guarded:
+  %cmp = icmp sgt i32 %n, 0
+  br i1 %cmp, label %then, label %merge
+
+then:
+  %add = fadd <4 x float> %a, %b
+  br label %merge
+
+merge:
+  %r = phi <4 x float> [ zeroinitializer, %entry ], [ %add, %then ], [ %b, %guarded ]
+  ret <4 x float> %r
+}
+
+define double @speculate_f64(i32 %n, double %a, double %b, i1 %other) {
+; CHECK-LABEL: define double @speculate_f64(
+; CHECK-SAME: i32 [[N:%.*]], double [[A:%.*]], double [[B:%.*]], i1 [[OTHER:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[N]], 0
+; CHECK-NEXT:    [[ADD:%.*]] = fadd double [[A]], [[B]]
+; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[CMP]], double [[ADD]], double [[B]]
+; CHECK-NEXT:    [[R:%.*]] = select i1 [[OTHER]], double 0.000000e+00, double [[SPEC_SELECT]]
+; CHECK-NEXT:    ret double [[R]]
+;
+entry:
+  br i1 %other, label %merge, label %guarded
+
+guarded:
+  %cmp = icmp sgt i32 %n, 0
+  br i1 %cmp, label %then, label %merge
+
+then:
+  %add = fadd double %a, %b
+  br label %merge
+
+merge:
+  %r = phi double [ 0.0, %entry ], [ %add, %then ], [ %b, %guarded ]
+  ret double %r
+}


        


More information about the llvm-commits mailing list