Index: lib/Transforms/InstCombine/InstCombineCasts.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineCasts.cpp +++ lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -1799,6 +1799,31 @@ /// All the related PHI nodes can be replaced by new PHI nodes with type A. /// The uses of \p CI can be changed to the new PHI node corresponding to \p PN. Instruction *InstCombiner::optimizeBitCastFromPhi(CastInst &CI, PHINode *PN) { + // Do not try to optimize the following case: + // ... + // Z = PHI [X, ... + // Y = BitCast (Z) + // store Y + // store Z + // As the optimization converts the case to: + // ... + // Zn = PHI [Xn, ... + // X = BitCast (Xn) + // store Zn + // store X + // Potentially leading to infinite loop. + bool Store = false; + for (User *U : PN->users()) { + auto *SI = dyn_cast(U); + if (SI && SI->isSimple() && SI->getOperand(0) == PN) + Store = true; + } + for (User *U : CI.users()) { + auto *SI = dyn_cast(U); + if (SI && SI->isSimple() && SI->getOperand(0) == &CI && Store) + return nullptr; + } + Value *Src = CI.getOperand(0); Type *SrcTy = Src->getType(); // Type B Type *DestTy = CI.getType(); // Type A Index: test/Transforms/InstCombine/bitcast-cycle.ll =================================================================== --- test/Transforms/InstCombine/bitcast-cycle.ll +++ test/Transforms/InstCombine/bitcast-cycle.ll @@ -0,0 +1,43 @@ +; RUN: opt < %s -S -instcombine | FileCheck %s +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" + +; This test case checks that BitCast optimization do not cycle. + +; CHECK: define i32 @foo + +@i = constant i32 1, align 4 +@f = constant float 0x3FF19999A0000000, align 4 +@cmp = common global i32 0, align 4 +@resf = common global float* null, align 8 +@resi = common global i32* null, align 8 + +; Function Attrs: norecurse nounwind uwtable +define i32 @foo() #0 { +entry: + br label %while.cond + +while.cond: ; preds = %if.then, %if.else, %entry + %res.0 = phi i32* [ null, %entry ], [ @i, %if.then ], [ bitcast (float* @f to i32*), %if.else ] + %0 = load i32, i32* @cmp, align 4 + %shr = ashr i32 %0, 1 + store i32 %shr, i32* @cmp, align 4 + %tobool = icmp ne i32 %shr, 0 + br i1 %tobool, label %while.body, label %while.end + +while.body: ; preds = %while.cond + %and = and i32 %shr, 1 + %tobool1 = icmp ne i32 %and, 0 + br i1 %tobool1, label %if.then, label %if.else + +if.then: ; preds = %while.body + br label %while.cond + +if.else: ; preds = %while.body + br label %while.cond + +while.end: ; preds = %while.cond + %1 = bitcast i32* %res.0 to float* + store float* %1, float** @resf, align 8 + store i32* %res.0, i32** @resi, align 8 + ret i32 0 +}