1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -S -passes=early-cse -earlycse-debug-hash | FileCheck %s 3; RUN: opt < %s -S -passes='early-cse<memssa>' | FileCheck %s 4 5define i64 @branching_int(i32 %a) { 6; CHECK-LABEL: @branching_int( 7; CHECK-NEXT: [[CONV1:%.*]] = zext i32 [[A:%.*]] to i64 8; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i64 1, [[CONV1]] 9; CHECK-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END3:%.*]] 10; CHECK: if.then3: 11; CHECK-NEXT: [[C:%.*]] = call double @truefunc.f64.i1(i1 true) 12; CHECK-NEXT: br label [[OUT:%.*]] 13; CHECK: if.end3: 14; CHECK-NEXT: [[D:%.*]] = call double @falsefunc.f64.i1(i1 false) 15; CHECK-NEXT: br label [[OUT]] 16; CHECK: out: 17; CHECK-NEXT: ret i64 [[CONV1]] 18; 19 %conv1 = zext i32 %a to i64 20 %cmp2 = icmp ugt i64 1, %conv1 21 br i1 %cmp2, label %if.then3, label %if.end3 22 23if.then3: 24 %c = call double @truefunc.f64.i1(i1 %cmp2) 25 br label %out 26 27if.end3: 28 %d = call double @falsefunc.f64.i1(i1 %cmp2) 29 br label %out 30 31out: 32 ret i64 %conv1 33} 34 35define double @branching_fp(i64 %a) { 36; CHECK-LABEL: @branching_fp( 37; CHECK-NEXT: [[CONV1:%.*]] = uitofp i64 [[A:%.*]] to double 38; CHECK-NEXT: [[CMP2:%.*]] = fcmp ogt double 1.000000e+00, [[CONV1]] 39; CHECK-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END3:%.*]] 40; CHECK: if.then3: 41; CHECK-NEXT: [[C:%.*]] = call double @truefunc.f64.i1(i1 true) 42; CHECK-NEXT: br label [[OUT:%.*]] 43; CHECK: if.end3: 44; CHECK-NEXT: [[D:%.*]] = call double @falsefunc.f64.i1(i1 false) 45; CHECK-NEXT: br label [[OUT]] 46; CHECK: out: 47; CHECK-NEXT: ret double [[CONV1]] 48; 49 %conv1 = uitofp i64 %a to double 50 %cmp2 = fcmp ogt double 1.000000e+00, %conv1 51 br i1 %cmp2, label %if.then3, label %if.end3 52 53if.then3: 54 %c = call double @truefunc.f64.i1(i1 %cmp2) 55 br label %out 56 57if.end3: 58 %d = call double @falsefunc.f64.i1(i1 %cmp2) 59 br label %out 60 61out: 62 ret double %conv1 63} 64 65define double @branching_exceptignore(i64 %a) #0 { 66; CHECK-LABEL: @branching_exceptignore( 67; CHECK-NEXT: [[CONV1:%.*]] = call double @llvm.experimental.constrained.uitofp.f64.i64(i64 [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0:[0-9]+]] 68; CHECK-NEXT: [[CMP2:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f64(double 1.000000e+00, double [[CONV1]], metadata !"ogt", metadata !"fpexcept.ignore") #[[ATTR0]] 69; CHECK-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END3:%.*]] 70; CHECK: if.then3: 71; CHECK-NEXT: [[C:%.*]] = call double @truefunc.f64.i1(i1 true) #[[ATTR0]] 72; CHECK-NEXT: br label [[OUT:%.*]] 73; CHECK: if.end3: 74; CHECK-NEXT: [[D:%.*]] = call double @falsefunc.f64.i1(i1 false) #[[ATTR0]] 75; CHECK-NEXT: br label [[OUT]] 76; CHECK: out: 77; CHECK-NEXT: ret double [[CONV1]] 78; 79 %conv1 = call double @llvm.experimental.constrained.uitofp.f64.i64(i64 %a, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0 80 %cmp2 = call i1 @llvm.experimental.constrained.fcmps.f64(double 1.000000e+00, double %conv1, metadata !"ogt", metadata !"fpexcept.ignore") #0 81 br i1 %cmp2, label %if.then3, label %if.end3 82 83if.then3: 84 %c = call double @truefunc.f64.i1(i1 %cmp2) #0 85 br label %out 86 87if.end3: 88 %d = call double @falsefunc.f64.i1(i1 %cmp2) #0 89 br label %out 90 91out: 92 ret double %conv1 93} 94 95define double @branching_exceptignore_dynround(i64 %a) #0 { 96; CHECK-LABEL: @branching_exceptignore_dynround( 97; CHECK-NEXT: [[CONV1:%.*]] = call double @llvm.experimental.constrained.uitofp.f64.i64(i64 [[A:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]] 98; CHECK-NEXT: [[CMP2:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f64(double 1.000000e+00, double [[CONV1]], metadata !"ogt", metadata !"fpexcept.ignore") #[[ATTR0]] 99; CHECK-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END3:%.*]] 100; CHECK: if.then3: 101; CHECK-NEXT: [[C:%.*]] = call double @truefunc.f64.i1(i1 true) #[[ATTR0]] 102; CHECK-NEXT: br label [[OUT:%.*]] 103; CHECK: if.end3: 104; CHECK-NEXT: [[D:%.*]] = call double @falsefunc.f64.i1(i1 false) #[[ATTR0]] 105; CHECK-NEXT: br label [[OUT]] 106; CHECK: out: 107; CHECK-NEXT: ret double [[CONV1]] 108; 109 %conv1 = call double @llvm.experimental.constrained.uitofp.f64.i64(i64 %a, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0 110 %cmp2 = call i1 @llvm.experimental.constrained.fcmps.f64(double 1.000000e+00, double %conv1, metadata !"ogt", metadata !"fpexcept.ignore") #0 111 br i1 %cmp2, label %if.then3, label %if.end3 112 113if.then3: 114 %c = call double @truefunc.f64.i1(i1 %cmp2) #0 115 br label %out 116 117if.end3: 118 %d = call double @falsefunc.f64.i1(i1 %cmp2) #0 119 br label %out 120 121out: 122 ret double %conv1 123} 124 125define double @branching_maytrap(i64 %a) #0 { 126; CHECK-LABEL: @branching_maytrap( 127; CHECK-NEXT: [[CONV1:%.*]] = call double @llvm.experimental.constrained.uitofp.f64.i64(i64 [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]] 128; CHECK-NEXT: [[CMP2:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f64(double 1.000000e+00, double [[CONV1]], metadata !"ogt", metadata !"fpexcept.maytrap") #[[ATTR0]] 129; CHECK-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END3:%.*]] 130; CHECK: if.then3: 131; CHECK-NEXT: [[C:%.*]] = call double @truefunc.f64.i1(i1 true) #[[ATTR0]] 132; CHECK-NEXT: br label [[OUT:%.*]] 133; CHECK: if.end3: 134; CHECK-NEXT: [[D:%.*]] = call double @falsefunc.f64.i1(i1 false) #[[ATTR0]] 135; CHECK-NEXT: br label [[OUT]] 136; CHECK: out: 137; CHECK-NEXT: ret double [[CONV1]] 138; 139 %conv1 = call double @llvm.experimental.constrained.uitofp.f64.i64(i64 %a, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0 140 %cmp2 = call i1 @llvm.experimental.constrained.fcmps.f64(double 1.000000e+00, double %conv1, metadata !"ogt", metadata !"fpexcept.maytrap") #0 141 br i1 %cmp2, label %if.then3, label %if.end3 142 143if.then3: 144 %c = call double @truefunc.f64.i1(i1 %cmp2) #0 145 br label %out 146 147if.end3: 148 %d = call double @falsefunc.f64.i1(i1 %cmp2) #0 149 br label %out 150 151out: 152 ret double %conv1 153} 154 155; TODO: Fix this optimization so it works with strict exception behavior. 156; TODO: This may or may not be worth the added complication and risk. 157define double @branching_ebstrict(i64 %a) #0 { 158; CHECK-LABEL: @branching_ebstrict( 159; CHECK-NEXT: [[CONV1:%.*]] = call double @llvm.experimental.constrained.uitofp.f64.i64(i64 [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]] 160; CHECK-NEXT: [[CMP2:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f64(double 1.000000e+00, double [[CONV1]], metadata !"ogt", metadata !"fpexcept.strict") #[[ATTR0]] 161; CHECK-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END3:%.*]] 162; CHECK: if.then3: 163; CHECK-NEXT: [[C:%.*]] = call double @truefunc.f64.i1(i1 [[CMP2]]) #[[ATTR0]] 164; CHECK-NEXT: br label [[OUT:%.*]] 165; CHECK: if.end3: 166; CHECK-NEXT: [[D:%.*]] = call double @falsefunc.f64.i1(i1 [[CMP2]]) #[[ATTR0]] 167; CHECK-NEXT: br label [[OUT]] 168; CHECK: out: 169; CHECK-NEXT: ret double [[CONV1]] 170; 171 %conv1 = call double @llvm.experimental.constrained.uitofp.f64.i64(i64 %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #0 172 %cmp2 = call i1 @llvm.experimental.constrained.fcmps.f64(double 1.000000e+00, double %conv1, metadata !"ogt", metadata !"fpexcept.strict") #0 173 br i1 %cmp2, label %if.then3, label %if.end3 174 175if.then3: 176 %c = call double @truefunc.f64.i1(i1 %cmp2) #0 177 br label %out 178 179if.end3: 180 %d = call double @falsefunc.f64.i1(i1 %cmp2) #0 181 br label %out 182 183out: 184 ret double %conv1 185} 186 187declare double @truefunc.f64.i1(i1) 188declare double @falsefunc.f64.i1(i1) 189declare double @llvm.experimental.constrained.uitofp.f64.i64(i64, metadata, metadata) #0 190declare i1 @llvm.experimental.constrained.fcmps.f64(double, double, metadata, metadata) #0 191 192attributes #0 = { strictfp } 193 194declare <4 x float> @llvm.experimental.constrained.fadd.v4f32(<4 x float>, <4 x float>, metadata, metadata) strictfp 195