return false;
}
+ if (FreezeInst *FI = dyn_cast<FreezeInst>(I)) {
+ // br(freeze(icmp a, const)) -> br(icmp (freeze a), const)
+ // This helps generate efficient conditional jumps.
+ if (ICmpInst *II = dyn_cast<ICmpInst>(FI->getOperand(0))) {
+ auto Op0 = II->getOperand(0), Op1 = II->getOperand(1);
+ bool Const0 = isa<ConstantInt>(Op0), Const1 = isa<ConstantInt>(Op1);
+ if (II->hasOneUse() && (Const0 || Const1)) {
+ if (!Const0 || !Const1) {
+ auto *F = new FreezeInst(Const0 ? Op1 : Op0, "", II);
+ F->takeName(FI);
+ II->setOperand(Const0 ? 1 : 0, F);
+ }
+ FI->replaceAllUsesWith(II);
+ FI->eraseFromParent();
+ return true;
+ }
+ }
+ return false;
+ }
+
if (tryToSinkFreeOperands(I))
return true;
--- /dev/null
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -codegenprepare < %s | FileCheck %s
+
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @f1(i32 %a) {
+; CHECK-LABEL: @f1(
+; CHECK-NEXT: [[FR1:%.*]] = freeze i32 [[A:%.*]]
+; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[FR1]], 0
+; CHECK-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]]
+; CHECK: A:
+; CHECK-NEXT: call void @g1()
+; CHECK-NEXT: ret void
+; CHECK: B:
+; CHECK-NEXT: call void @g2()
+; CHECK-NEXT: ret void
+;
+ %c = icmp eq i32 %a, 0
+ %fr = freeze i1 %c
+ br i1 %fr, label %A, label %B
+A:
+ call void @g1()
+ ret void
+B:
+ call void @g2()
+ ret void
+}
+
+define void @f2(i32 %a) {
+; CHECK-LABEL: @f2(
+; CHECK-NEXT: [[FR1:%.*]] = freeze i32 [[A:%.*]]
+; CHECK-NEXT: [[C:%.*]] = icmp eq i32 0, [[FR1]]
+; CHECK-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]]
+; CHECK: A:
+; CHECK-NEXT: call void @g1()
+; CHECK-NEXT: ret void
+; CHECK: B:
+; CHECK-NEXT: call void @g2()
+; CHECK-NEXT: ret void
+;
+ %c = icmp eq i32 0, %a
+ %fr = freeze i1 %c
+ br i1 %fr, label %A, label %B
+A:
+ call void @g1()
+ ret void
+B:
+ call void @g2()
+ ret void
+}
+
+define void @f3(i32 %a) {
+; CHECK-LABEL: @f3(
+; CHECK-NEXT: [[C:%.*]] = icmp eq i32 0, 1
+; CHECK-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]]
+; CHECK: A:
+; CHECK-NEXT: call void @g1()
+; CHECK-NEXT: ret void
+; CHECK: B:
+; CHECK-NEXT: call void @g2()
+; CHECK-NEXT: ret void
+;
+ %c = icmp eq i32 0, 1
+ %fr = freeze i1 %c
+ br i1 %fr, label %A, label %B
+A:
+ call void @g1()
+ ret void
+B:
+ call void @g2()
+ ret void
+}
+
+declare void @g1()
+declare void @g2()