Index: llvm/lib/IR/ConstantFold.cpp =================================================================== --- llvm/lib/IR/ConstantFold.cpp +++ llvm/lib/IR/ConstantFold.cpp @@ -1751,9 +1751,15 @@ case Instruction::FPToSI: break; // We can't evaluate floating point casts or truncations. + case Instruction::BitCast: + // If this is a global value cast, check to see if the RHS is also a + // GlobalValue. + if (const GlobalValue *GV = dyn_cast(CE1Op0)) + if (const GlobalValue *GV2 = dyn_cast(V2)) + return areGlobalsPotentiallyEqual(GV, GV2); + LLVM_FALLTHROUGH; case Instruction::UIToFP: case Instruction::SIToFP: - case Instruction::BitCast: case Instruction::ZExt: case Instruction::SExt: // We can't evaluate floating point casts or truncations. Index: llvm/test/Transforms/InstCombine/icmp-bitcast-func.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/InstCombine/icmp-bitcast-func.ll @@ -0,0 +1,20 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s + +declare i32 @f32(i32**, i32**) + +declare i32 @f64(i64**, i64**) + +define i1 @icmp_func() { +; CHECK-LABEL: @icmp_func( +; CHECK: ret i1 false + %cmp = icmp eq i32 (i8*, i8*)* bitcast (i32 (i32**, i32**)* @f32 to i32 (i8*, i8*)*), bitcast (i32 (i64**, i64**)* @f64 to i32 (i8*, i8*)*) + ret i1 %cmp +} + +define i1 @icmp_fptr(i32 (i8*, i8*)*) { +; CHECK-LABEL: @icmp_fptr( +; CHECK: %cmp = icmp ne i32 (i8*, i8*)* %0, bitcast (i32 (i32**, i32**)* @f32 to i32 (i8*, i8*)*) +; CHECK: ret i1 %cmp + %cmp = icmp ne i32 (i8*, i8*)* bitcast (i32 (i32**, i32**)* @f32 to i32 (i8*, i8*)*), %0 + ret i1 %cmp +} Index: llvm/test/Transforms/InstCombine/pr32686.ll =================================================================== --- llvm/test/Transforms/InstCombine/pr32686.ll +++ llvm/test/Transforms/InstCombine/pr32686.ll @@ -1,8 +1,9 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -S -instcombine %s | FileCheck %s -@a = external global i8 +@a = common global i8 0, align 1 @b = external global i32 +@a2 = external global i8 define void @tinkywinky() { ; CHECK-LABEL: @tinkywinky( @@ -21,3 +22,18 @@ store i32 %or, i32* @b, align 4 ret void } + +define void @tinkywinky2() { +; CHECK-LABEL: @tinkywinky2( +; CHECK-NEXT: store i32 3, i32* @b, align 4 +; CHECK-NEXT: ret void +; + %patatino = load i8, i8* @a2 + %tobool = icmp ne i8 %patatino, 0 + %lnot = xor i1 %tobool, true + %lnot.ext = zext i1 %lnot to i32 + %or = or i32 xor (i32 zext (i1 icmp ne (i32* bitcast (i8* @a2 to i32*), i32* @b) to i32), i32 2), %lnot.ext + store i32 %or, i32* @b, align 4 + ret void +} + Index: llvm/test/Transforms/SCCP/ip-ranges-select.ll =================================================================== --- llvm/test/Transforms/SCCP/ip-ranges-select.ll +++ llvm/test/Transforms/SCCP/ip-ranges-select.ll @@ -107,7 +107,8 @@ ret i1 %res } -@GV = external global i32 +@GV = common global i32 0, align 4 +@GV2 = external global i32 define i32 @f3_constantexpr_cond(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @f3_constantexpr_cond(i32 %x, i32 %y) @@ -118,6 +119,15 @@ ret i32 %sel.1 } +define i32 @f3_constantexpr_cond2(i32 %x, i32 %y) { +; CHECK-LABEL: define i32 @f3_constantexpr_cond2(i32 %x, i32 %y) +; CHECK-NEXT: %sel.1 = select i1 false, i32 %x, i32 %y +; CHECK-NEXT: ret i32 %sel.1 +; + %sel.1 = select i1 icmp eq (i32* bitcast (i32 (i32, i32)* @f3_constantexpr_cond to i32*), i32* @GV2), i32 %x, i32 %y + ret i32 %sel.1 +} + define i32 @caller3(i32 %y) { ; CHECK-LABEL: define i32 @caller3(i32 %y) { ; CHECK-NEXT: %call.1 = tail call i32 @f3_constantexpr_cond(i32 10, i32 %y) Index: llvm/test/Transforms/SCCP/undef-resolve.ll =================================================================== --- llvm/test/Transforms/SCCP/undef-resolve.ll +++ llvm/test/Transforms/SCCP/undef-resolve.ll @@ -254,7 +254,8 @@ ret i64 %e } -@GV = external global i32 +@GV = common global i32 0, align 4 +@GV2 = external global i32 define i32 @test11(i1 %tobool) { ; CHECK-LABEL: @test11( @@ -276,3 +277,15 @@ %t = fneg double undef ret double %t } + + +define i32 @test13(i1 %tobool) { +; CHECK-LABEL: @test13( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[SHR4:%.*]] = ashr i32 undef, 0 +; CHECK-NEXT: ret i32 [[SHR4]] +; +entry: + %shr4 = ashr i32 undef, zext (i1 icmp eq (i32* bitcast (i32 (i1)* @test11 to i32*), i32* @GV2) to i32) + ret i32 %shr4 +}