diff --git a/llvm/lib/Transforms/Scalar/GuardWidening.cpp b/llvm/lib/Transforms/Scalar/GuardWidening.cpp --- a/llvm/lib/Transforms/Scalar/GuardWidening.cpp +++ b/llvm/lib/Transforms/Scalar/GuardWidening.cpp @@ -552,6 +552,8 @@ if (InsertPt) { ConstantInt *NewRHS = ConstantInt::get(Cond0->getContext(), NewRHSAP); + assert(isAvailableAt(LHS, InsertPt) && "must be"); + makeAvailableAt(LHS, InsertPt); Result = new ICmpInst(InsertPt, Pred, LHS, NewRHS, "wide.chk"); } return true; diff --git a/llvm/test/Transforms/GuardWidening/widen-cond-with-operands.ll b/llvm/test/Transforms/GuardWidening/widen-cond-with-operands.ll --- a/llvm/test/Transforms/GuardWidening/widen-cond-with-operands.ll +++ b/llvm/test/Transforms/GuardWidening/widen-cond-with-operands.ll @@ -1,13 +1,31 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -S -passes=guard-widening,verify < %s | FileCheck %s target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128-ni:1-p2:32:8:8:32-ni:2" target triple = "x86_64-unknown-linux-gnu" -; REQUIRES: asserts -; XFAIL: * - -; GuardWidening moves 'check' instruction before 'wc1' without its operand ('zero'). -; This is incorrect as 'zero' is not available at that point. +; Make sure GuardWidening moves 'check' instruction before 'wc1' together with its operand - 'zero'. define void @foo() { +; CHECK-LABEL: @foo( +; CHECK-NEXT: bb: +; CHECK-NEXT: [[ZERO:%.*]] = add i32 0, 0 +; CHECK-NEXT: [[WIDE_CHK:%.*]] = icmp ult i32 [[ZERO]], 0 +; CHECK-NEXT: [[WC1:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition() +; CHECK-NEXT: [[CHECK:%.*]] = icmp ult i32 [[ZERO]], 0 +; CHECK-NEXT: [[C2:%.*]] = and i1 [[CHECK]], [[WC2]] +; CHECK-NEXT: [[C1:%.*]] = and i1 [[WIDE_CHK]], [[WC1]] +; CHECK-NEXT: br i1 [[C1]], label [[BB6:%.*]], label [[BB9:%.*]] +; CHECK: bb6: +; CHECK-NEXT: br i1 true, label [[BB7:%.*]], label [[BB8:%.*]] +; CHECK: bb7: +; CHECK-NEXT: ret void +; CHECK: bb8: +; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid(i32 0) [ "deopt"() ] +; CHECK-NEXT: ret void +; CHECK: bb9: +; CHECK-NEXT: call void (...) @llvm.experimental.deoptimize.isVoid(i32 0) [ "deopt"() ] +; CHECK-NEXT: ret void +; bb: %wc1 = call i1 @llvm.experimental.widenable.condition() %wc2 = call i1 @llvm.experimental.widenable.condition()