417 changes: 417 additions & 0 deletions llvm/test/Transforms/EarlyCSE/mixed-strictfp.ll

Large diffs are not rendered by default.

405 changes: 405 additions & 0 deletions llvm/test/Transforms/EarlyCSE/nonmixed-strictfp.ll

Large diffs are not rendered by default.

222 changes: 222 additions & 0 deletions llvm/test/Transforms/EarlyCSE/round-dyn-strictfp.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -S -early-cse -earlycse-debug-hash | FileCheck %s
; RUN: opt < %s -S -basic-aa -early-cse-memssa | FileCheck %s

; Test use of constrained floating point intrinsics with dynamic
; rounding mode. Dynamic rounding _must_ disable CSE since EarlyCSE
; will CSE across function calls and we cannot know if the rounding
; mode will be changed by any arbitrary function call.

define double @multiple_fadd(double %a, double %b) #0 {
; CHECK-LABEL: @multiple_fadd(
; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0:[0-9]+]]
; CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[A]], double [[B]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
; CHECK-NEXT: ret double [[TMP2]]
;
%1 = call double @llvm.experimental.constrained.fadd.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
%2 = call double @llvm.experimental.constrained.fadd.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
%3 = call double @foo.f64(double %1, double %2) #0
ret double %2
}

define double @multiple_fadd_split(double %a, double %b) #0 {
; CHECK-LABEL: @multiple_fadd_split(
; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: call void @arbitraryfunc() #[[ATTR0]]
; CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double [[A]], double [[B]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
; CHECK-NEXT: ret double [[TMP2]]
;
%1 = call double @llvm.experimental.constrained.fadd.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
call void @arbitraryfunc() #0
%2 = call double @llvm.experimental.constrained.fadd.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
%3 = call double @foo.f64(double %1, double %2) #0
ret double %2
}

define double @multiple_fsub(double %a, double %b) #0 {
; CHECK-LABEL: @multiple_fsub(
; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.experimental.constrained.fsub.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.experimental.constrained.fsub.f64(double [[A]], double [[B]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
; CHECK-NEXT: ret double [[TMP2]]
;
%1 = call double @llvm.experimental.constrained.fsub.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
%2 = call double @llvm.experimental.constrained.fsub.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
%3 = call double @foo.f64(double %1, double %2) #0
ret double %2
}

define double @multiple_fsub_split(double %a, double %b) #0 {
; CHECK-LABEL: @multiple_fsub_split(
; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.experimental.constrained.fsub.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: call void @arbitraryfunc() #[[ATTR0]]
; CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.experimental.constrained.fsub.f64(double [[A]], double [[B]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
; CHECK-NEXT: ret double [[TMP2]]
;
%1 = call double @llvm.experimental.constrained.fsub.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
call void @arbitraryfunc() #0
%2 = call double @llvm.experimental.constrained.fsub.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
%3 = call double @foo.f64(double %1, double %2) #0
ret double %2
}

define double @multiple_fmul(double %a, double %b) #0 {
; CHECK-LABEL: @multiple_fmul(
; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[A]], double [[B]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
; CHECK-NEXT: ret double [[TMP2]]
;
%1 = call double @llvm.experimental.constrained.fmul.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
%2 = call double @llvm.experimental.constrained.fmul.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
%3 = call double @foo.f64(double %1, double %2) #0
ret double %2
}

define double @multiple_fmul_split(double %a, double %b) #0 {
; CHECK-LABEL: @multiple_fmul_split(
; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: call void @arbitraryfunc() #[[ATTR0]]
; CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.experimental.constrained.fmul.f64(double [[A]], double [[B]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
; CHECK-NEXT: ret double [[TMP2]]
;
%1 = call double @llvm.experimental.constrained.fmul.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
call void @arbitraryfunc() #0
%2 = call double @llvm.experimental.constrained.fmul.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
%3 = call double @foo.f64(double %1, double %2) #0
ret double %2
}

define double @multiple_fdiv(double %a, double %b) #0 {
; CHECK-LABEL: @multiple_fdiv(
; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[A]], double [[B]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
; CHECK-NEXT: ret double [[TMP2]]
;
%1 = call double @llvm.experimental.constrained.fdiv.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
%2 = call double @llvm.experimental.constrained.fdiv.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
%3 = call double @foo.f64(double %1, double %2) #0
ret double %2
}

define double @multiple_fdiv_split(double %a, double %b) #0 {
; CHECK-LABEL: @multiple_fdiv_split(
; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: call void @arbitraryfunc() #[[ATTR0]]
; CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[A]], double [[B]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
; CHECK-NEXT: ret double [[TMP2]]
;
%1 = call double @llvm.experimental.constrained.fdiv.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
call void @arbitraryfunc() #0
%2 = call double @llvm.experimental.constrained.fdiv.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
%3 = call double @foo.f64(double %1, double %2) #0
ret double %2
}

define double @multiple_frem(double %a, double %b) #0 {
; CHECK-LABEL: @multiple_frem(
; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.experimental.constrained.frem.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.experimental.constrained.frem.f64(double [[A]], double [[B]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
; CHECK-NEXT: ret double [[TMP2]]
;
%1 = call double @llvm.experimental.constrained.frem.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
%2 = call double @llvm.experimental.constrained.frem.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
%3 = call double @foo.f64(double %1, double %2) #0
ret double %2
}

define double @multiple_frem_split(double %a, double %b) #0 {
; CHECK-LABEL: @multiple_frem_split(
; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.experimental.constrained.frem.f64(double [[A:%.*]], double [[B:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: call void @arbitraryfunc() #[[ATTR0]]
; CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.experimental.constrained.frem.f64(double [[A]], double [[B]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP2]]) #[[ATTR0]]
; CHECK-NEXT: ret double [[TMP2]]
;
%1 = call double @llvm.experimental.constrained.frem.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
call void @arbitraryfunc() #0
%2 = call double @llvm.experimental.constrained.frem.f64(double %a, double %b, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
%3 = call double @foo.f64(double %1, double %2) #0
ret double %2
}

define double @multiple_uitofp(i32 %a) #0 {
; CHECK-LABEL: @multiple_uitofp(
; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 [[A:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 [[A]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP1]]) #[[ATTR0]]
; CHECK-NEXT: ret double [[TMP2]]
;
%1 = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
%2 = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
%3 = call double @foo.f64(double %1, double %1) #0
ret double %2
}

define double @multiple_uitofp_split(i32 %a) #0 {
; CHECK-LABEL: @multiple_uitofp_split(
; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 [[A:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: call void @arbitraryfunc() #[[ATTR0]]
; CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 [[A]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP1]]) #[[ATTR0]]
; CHECK-NEXT: ret double [[TMP2]]
;
%1 = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
call void @arbitraryfunc() #0
%2 = call double @llvm.experimental.constrained.uitofp.f64.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
%3 = call double @foo.f64(double %1, double %1) #0
ret double %2
}

define double @multiple_sitofp(i32 %a) #0 {
; CHECK-LABEL: @multiple_sitofp(
; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 [[A:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 [[A]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP1]]) #[[ATTR0]]
; CHECK-NEXT: ret double [[TMP2]]
;
%1 = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
%2 = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
%3 = call double @foo.f64(double %1, double %1) #0
ret double %2
}

define double @multiple_sitofp_split(i32 %a) #0 {
; CHECK-LABEL: @multiple_sitofp_split(
; CHECK-NEXT: [[TMP1:%.*]] = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 [[A:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: call void @arbitraryfunc() #[[ATTR0]]
; CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 [[A]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: [[TMP3:%.*]] = call double @foo.f64(double [[TMP1]], double [[TMP1]]) #[[ATTR0]]
; CHECK-NEXT: ret double [[TMP2]]
;
%1 = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
call void @arbitraryfunc() #0
%2 = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
%3 = call double @foo.f64(double %1, double %1) #0
ret double %2
}

attributes #0 = { strictfp }

declare void @arbitraryfunc() #0
declare double @foo.f64(double, double) #0
declare i32 @bar.i32(i32, i32) #0

declare double @llvm.experimental.constrained.fadd.f64(double, double, metadata, metadata)
declare double @llvm.experimental.constrained.fsub.f64(double, double, metadata, metadata)
declare double @llvm.experimental.constrained.fmul.f64(double, double, metadata, metadata)
declare double @llvm.experimental.constrained.fdiv.f64(double, double, metadata, metadata)
declare double @llvm.experimental.constrained.frem.f64(double, double, metadata, metadata)
declare i32 @llvm.experimental.constrained.fptoui.i32.f64(double, metadata)
declare double @llvm.experimental.constrained.uitofp.f64.i32(i32, metadata, metadata)
declare i32 @llvm.experimental.constrained.fptosi.i32.f64(double, metadata)
declare double @llvm.experimental.constrained.sitofp.f64.i32(i32, metadata, metadata)
declare i1 @llvm.experimental.constrained.fcmp.i1.f64(double, double, metadata, metadata)
declare i1 @llvm.experimental.constrained.fcmps.i1.f64(double, double, metadata, metadata)
162 changes: 162 additions & 0 deletions llvm/test/Transforms/EarlyCSE/tfpropagation.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -S -early-cse -earlycse-debug-hash | FileCheck %s
; RUN: opt < %s -S -basic-aa -early-cse-memssa | FileCheck %s

define i64 @branching_int(i32 %a) {
; CHECK-LABEL: @branching_int(
; CHECK-NEXT: [[CONV1:%.*]] = zext i32 [[A:%.*]] to i64
; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i64 1, [[CONV1]]
; CHECK-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END3:%.*]]
; CHECK: if.then3:
; CHECK-NEXT: [[C:%.*]] = call double @truefunc.f64.i1(i1 true)
; CHECK-NEXT: br label [[OUT:%.*]]
; CHECK: if.end3:
; CHECK-NEXT: [[D:%.*]] = call double @falsefunc.f64.i1(i1 false)
; CHECK-NEXT: br label [[OUT]]
; CHECK: out:
; CHECK-NEXT: ret i64 [[CONV1]]
;
%conv1 = zext i32 %a to i64
%cmp2 = icmp ugt i64 1, %conv1
br i1 %cmp2, label %if.then3, label %if.end3

if.then3:
%c = call double @truefunc.f64.i1(i1 %cmp2)
br label %out

if.end3:
%d = call double @falsefunc.f64.i1(i1 %cmp2)
br label %out

out:
ret i64 %conv1
}

define double @branching_fp(i64 %a) {
; CHECK-LABEL: @branching_fp(
; CHECK-NEXT: [[CONV1:%.*]] = uitofp i64 [[A:%.*]] to double
; CHECK-NEXT: [[CMP2:%.*]] = fcmp ogt double 1.000000e+00, [[CONV1]]
; CHECK-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END3:%.*]]
; CHECK: if.then3:
; CHECK-NEXT: [[C:%.*]] = call double @truefunc.f64.i1(i1 true)
; CHECK-NEXT: br label [[OUT:%.*]]
; CHECK: if.end3:
; CHECK-NEXT: [[D:%.*]] = call double @falsefunc.f64.i1(i1 false)
; CHECK-NEXT: br label [[OUT]]
; CHECK: out:
; CHECK-NEXT: ret double [[CONV1]]
;
%conv1 = uitofp i64 %a to double
%cmp2 = fcmp ogt double 1.000000e+00, %conv1
br i1 %cmp2, label %if.then3, label %if.end3

if.then3:
%c = call double @truefunc.f64.i1(i1 %cmp2)
br label %out

if.end3:
%d = call double @falsefunc.f64.i1(i1 %cmp2)
br label %out

out:
ret double %conv1
}

define double @branching_exceptignore(i64 %a) #0 {
; CHECK-LABEL: @branching_exceptignore(
; CHECK-NEXT: [[CONV1:%.*]] = call double @llvm.experimental.constrained.uitofp.f64.i64(i64 [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0:[0-9]+]]
; CHECK-NEXT: [[CMP2:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f64(double 1.000000e+00, double [[CONV1]], metadata !"ogt", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END3:%.*]]
; CHECK: if.then3:
; CHECK-NEXT: [[C:%.*]] = call double @truefunc.f64.i1(i1 true) #[[ATTR0]]
; CHECK-NEXT: br label [[OUT:%.*]]
; CHECK: if.end3:
; CHECK-NEXT: [[D:%.*]] = call double @falsefunc.f64.i1(i1 false) #[[ATTR0]]
; CHECK-NEXT: br label [[OUT]]
; CHECK: out:
; CHECK-NEXT: ret double [[CONV1]]
;
%conv1 = call double @llvm.experimental.constrained.uitofp.f64.i64(i64 %a, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
%cmp2 = call i1 @llvm.experimental.constrained.fcmps.f64(double 1.000000e+00, double %conv1, metadata !"ogt", metadata !"fpexcept.ignore") #0
br i1 %cmp2, label %if.then3, label %if.end3

if.then3:
%c = call double @truefunc.f64.i1(i1 %cmp2) #0
br label %out

if.end3:
%d = call double @falsefunc.f64.i1(i1 %cmp2) #0
br label %out

out:
ret double %conv1
}

define double @branching_exceptignore_dynround(i64 %a) #0 {
; CHECK-LABEL: @branching_exceptignore_dynround(
; CHECK-NEXT: [[CONV1:%.*]] = call double @llvm.experimental.constrained.uitofp.f64.i64(i64 [[A:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: [[CMP2:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f64(double 1.000000e+00, double [[CONV1]], metadata !"ogt", metadata !"fpexcept.ignore") #[[ATTR0]]
; CHECK-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END3:%.*]]
; CHECK: if.then3:
; CHECK-NEXT: [[C:%.*]] = call double @truefunc.f64.i1(i1 true) #[[ATTR0]]
; CHECK-NEXT: br label [[OUT:%.*]]
; CHECK: if.end3:
; CHECK-NEXT: [[D:%.*]] = call double @falsefunc.f64.i1(i1 false) #[[ATTR0]]
; CHECK-NEXT: br label [[OUT]]
; CHECK: out:
; CHECK-NEXT: ret double [[CONV1]]
;
%conv1 = call double @llvm.experimental.constrained.uitofp.f64.i64(i64 %a, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
%cmp2 = call i1 @llvm.experimental.constrained.fcmps.f64(double 1.000000e+00, double %conv1, metadata !"ogt", metadata !"fpexcept.ignore") #0
br i1 %cmp2, label %if.then3, label %if.end3

if.then3:
%c = call double @truefunc.f64.i1(i1 %cmp2) #0
br label %out

if.end3:
%d = call double @falsefunc.f64.i1(i1 %cmp2) #0
br label %out

out:
ret double %conv1
}

define double @branching_maytrap(i64 %a) #0 {
; CHECK-LABEL: @branching_maytrap(
; CHECK-NEXT: [[CONV1:%.*]] = call double @llvm.experimental.constrained.uitofp.f64.i64(i64 [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
; CHECK-NEXT: [[CMP2:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f64(double 1.000000e+00, double [[CONV1]], metadata !"ogt", metadata !"fpexcept.maytrap") #[[ATTR0]]
; CHECK-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END3:%.*]]
; CHECK: if.then3:
; CHECK-NEXT: [[C:%.*]] = call double @truefunc.f64.i1(i1 [[CMP2]]) #[[ATTR0]]
; CHECK-NEXT: br label [[OUT:%.*]]
; CHECK: if.end3:
; CHECK-NEXT: [[D:%.*]] = call double @falsefunc.f64.i1(i1 [[CMP2]]) #[[ATTR0]]
; CHECK-NEXT: br label [[OUT]]
; CHECK: out:
; CHECK-NEXT: ret double [[CONV1]]
;
%conv1 = call double @llvm.experimental.constrained.uitofp.f64.i64(i64 %a, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
%cmp2 = call i1 @llvm.experimental.constrained.fcmps.f64(double 1.000000e+00, double %conv1, metadata !"ogt", metadata !"fpexcept.maytrap") #0
br i1 %cmp2, label %if.then3, label %if.end3

if.then3:
%c = call double @truefunc.f64.i1(i1 %cmp2) #0
br label %out

if.end3:
%d = call double @falsefunc.f64.i1(i1 %cmp2) #0
br label %out

out:
ret double %conv1
}

declare double @truefunc.f64.i1(i1)
declare double @falsefunc.f64.i1(i1)
declare double @llvm.experimental.constrained.uitofp.f64.i64(i64, metadata, metadata) #0
declare i1 @llvm.experimental.constrained.fcmps.f64(double, double, metadata, metadata) #0

attributes #0 = { strictfp }

declare <4 x float> @llvm.experimental.constrained.fadd.v4f32(<4 x float>, <4 x float>, metadata, metadata) strictfp