Index: lib/Analysis/ValueTracking.cpp =================================================================== --- lib/Analysis/ValueTracking.cpp +++ lib/Analysis/ValueTracking.cpp @@ -793,22 +793,11 @@ return; } - // A weak GlobalAlias is totally unknown. A non-weak GlobalAlias has - // the bits of its aliasee. - if (GlobalAlias *GA = dyn_cast(V)) { - if (GA->mayBeOverridden()) { - KnownZero.clearAllBits(); KnownOne.clearAllBits(); - } else { - computeKnownBits(GA->getAliasee(), KnownZero, KnownOne, TD, Depth+1, Q); - } - return; - } - // The address of an aligned GlobalValue has trailing zeros. - if (GlobalValue *GV = dyn_cast(V)) { - unsigned Align = GV->getAlignment(); + if (GlobalObject *GO = dyn_cast(V)) { + unsigned Align = GO->getAlignment(); if (Align == 0 && TD) { - if (GlobalVariable *GVar = dyn_cast(GV)) { + if (GlobalVariable *GVar = dyn_cast(GO)) { Type *ObjectType = GVar->getType()->getElementType(); if (ObjectType->isSized()) { // If the object is defined in the current Module, we'll be giving @@ -855,6 +844,17 @@ if (Depth == MaxDepth) return; // Limit search depth. + // A weak GlobalAlias is totally unknown. A non-weak GlobalAlias has + // the bits of its aliasee. + if (GlobalAlias *GA = dyn_cast(V)) { + if (GA->mayBeOverridden()) { + KnownZero.clearAllBits(); KnownOne.clearAllBits(); + } else { + computeKnownBits(GA->getAliasee(), KnownZero, KnownOne, TD, Depth+1, Q); + } + return; + } + // Check whether a nearby assume intrinsic can determine some known bits. computeKnownBitsFromAssume(V, KnownZero, KnownOne, TD, Depth, Q); Index: test/Transforms/InstCombine/alias-recursion.ll =================================================================== --- test/Transforms/InstCombine/alias-recursion.ll +++ test/Transforms/InstCombine/alias-recursion.ll @@ -0,0 +1,45 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-windows-msvc" + +%rtti.CompleteObjectLocator = type { i32, i32, i32, i32, i32, i32 } +%rtti.TypeDescriptor = type { i8**, i8*, [8 x i8] } +%rtti.ClassHierarchyDescriptor = type { i32, i32, i32, i32 } +%rtti.BaseClassDescriptor = type { i32, i32, i32, i32, i32, i32, i32 } +%class.A = type { i32 (...)** } + +@0 = private unnamed_addr constant [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4A@@6B@" to i8*), i8* bitcast (i32 (%class.A*)* @"\01?virt@A@@UEAAHXZ" to i8*)] +@"\01??_R4A@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor* @"\01??_R0?AVA@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4A@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } +@"\01??_7type_info@@6B@" = external constant i8* +@"\01??_R0?AVA@@@8" = linkonce_odr global %rtti.TypeDescriptor { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVA@@\00" } +@__ImageBase = external constant i8 +@"\01??_R3A@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } +@"\01??_R2A@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0] +@"\01??_R1A@?0A@EA@A@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor* @"\01??_R0?AVA@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } +@"\01??_7A@@6B@" = unnamed_addr alias getelementptr inbounds ([2 x i8*]* @0, i32 0, i32 1) + +define void @test() { +; CHECK-LABEL: test +entry: + br i1 undef, label %for.body.lr.ph, label %for.end + +for.body.lr.ph: ; preds = %entry + br label %for.body + +for.body: ; preds = %for.body.for.body_crit_edge, %for.body.lr.ph + %vtable = phi i32 (%class.A*)** [ bitcast (i8** @"\01??_7A@@6B@" to i32 (%class.A*)**), %for.body.lr.ph ], [ null, %for.body.for.body_crit_edge ] + %0 = load i32 (%class.A*)** %vtable, align 8 + %call2 = tail call i32 %0(%class.A* undef) + br i1 undef, label %for.body.for.body_crit_edge, label %for.end + +for.body.for.body_crit_edge: ; preds = %for.body + br label %for.body + +for.end: ; preds = %for.body, %entry + ret void +} + +declare i32 @"\01?virt@A@@UEAAHXZ"(%class.A*) unnamed_addr align 2 + +