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/2004-11-27-SetCCForCastLargerAndConstant.ll =================================================================== --- llvm/test/Transforms/InstCombine/2004-11-27-SetCCForCastLargerAndConstant.ll +++ llvm/test/Transforms/InstCombine/2004-11-27-SetCCForCastLargerAndConstant.ll @@ -27,11 +27,22 @@ @a = common global i32** null @b = common global [1 x i32] zeroinitializer +@aa = alias i32**, i32*** @a define i1 @PR28011(i16 %a) { ; CHECK-LABEL: @PR28011( ; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[A:%.*]] to i32 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[CONV]], or (i32 zext (i1 icmp ne (i32*** bitcast ([1 x i32]* @b to i32***), i32*** @a) to i32), i32 1) +; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[CONV]], or (i32 zext (i1 icmp ne (i32*** bitcast ([1 x i32]* @b to i32***), i32*** @aa) to i32), i32 1) +; CHECK-NEXT: ret i1 [[CMP]] +; + %conv = sext i16 %a to i32 + %cmp = icmp ne i32 %conv, or (i32 zext (i1 icmp ne (i32*** bitcast ([1 x i32]* @b to i32***), i32*** @aa) to i32), i32 1) + ret i1 %cmp +} + +define i1 @PR28011a(i16 %a) { +; CHECK-LABEL: @PR28011a( +; CHECK-NEXT: [[CMP:%.*]] = icmp ne i16 [[A:%.*]], 1 ; CHECK-NEXT: ret i1 [[CMP]] ; %conv = sext i16 %a to i32 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 @@ -6,11 +6,7 @@ define void @tinkywinky() { ; CHECK-LABEL: @tinkywinky( -; CHECK-NEXT: [[PATATINO:%.*]] = load i8, i8* @a, align 1 -; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i8 [[PATATINO]], 0 -; CHECK-NEXT: [[TMP1:%.*]] = zext i1 [[TOBOOL]] to i32 -; CHECK-NEXT: [[OR1:%.*]] = or i32 [[TMP1]], or (i32 zext (i1 icmp ne (i32* bitcast (i8* @a to i32*), i32* @b) to i32), i32 2) -; CHECK-NEXT: store i32 [[OR1]], i32* @b, align 4 +; CHECK-NEXT: store i32 3, i32* @b, align 4 ; CHECK-NEXT: ret void ; %patatino = load i8, i8* @a 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 @@ -111,7 +111,7 @@ define i32 @f3_constantexpr_cond(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @f3_constantexpr_cond(i32 %x, i32 %y) -; CHECK-NEXT: %sel.1 = select i1 icmp eq (i32* bitcast (i32 (i32, i32)* @f3_constantexpr_cond to i32*), i32* @GV), 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* @GV), i32 %x, i32 %y Index: llvm/test/Transforms/SCCP/undef-resolve.ll =================================================================== --- llvm/test/Transforms/SCCP/undef-resolve.ll +++ llvm/test/Transforms/SCCP/undef-resolve.ll @@ -259,7 +259,7 @@ define i32 @test11(i1 %tobool) { ; CHECK-LABEL: @test11( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[SHR4:%.*]] = ashr i32 undef, zext (i1 icmp eq (i32* bitcast (i32 (i1)* @test11 to i32*), i32* @GV) to i32) +; CHECK-NEXT: [[SHR4:%.*]] = ashr i32 undef, 0 ; CHECK-NEXT: ret i32 [[SHR4]] ; entry: Index: llvm/test/Transforms/SimplifyCFG/PR17073.ll =================================================================== --- llvm/test/Transforms/SimplifyCFG/PR17073.ll +++ llvm/test/Transforms/SimplifyCFG/PR17073.ll @@ -11,8 +11,9 @@ target datalayout = "e-m:o-p:32:32-f64:32:64-f80:128-n8:16:32-S128" target triple = "i386-apple-macosx10.9.0" -@a = common global i32 0, align 4 +@g = common global i32 0, align 4 @b = common global i8 0, align 1 +@a = alias i32, i32* @g define i32* @can_trap1() { ; CHECK-LABEL: @can_trap1( @@ -98,3 +99,75 @@ %storemerge = phi i32* [ null, %entry ],[ null, %block2 ], [ select (i1 icmp eq (i64 add (i64 2, i64 zext (i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @a) to i64)), i64 0), i32* null, i32* @a), %block1 ] ret i32* %storemerge } + +; The following are the original test cases using global @g, and can be simplified now. + +define i32* @no_trap1() { +; CHECK-LABEL: @no_trap1( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @g, align 4 +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP0]], 0 +; CHECK-NEXT: ret i32* null +; +entry: + %0 = load i32, i32* @g, align 4 + %tobool = icmp eq i32 %0, 0 + br i1 %tobool, label %exit, label %block1 + +block1: + br i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @g), label %exit, label %block2 + +block2: + br label %exit + +exit: + %storemerge = phi i32* [ null, %entry ],[ null, %block2 ], [ select (i1 icmp eq (i64 urem (i64 2, i64 zext (i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @g) to i64)), i64 0), i32* null, i32* @g), %block1 ] + ret i32* %storemerge +} + +define i32* @no_trap2() { +; CHECK-LABEL: @no_trap2( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @g, align 4 +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP0]], 0 +; CHECK-NEXT: [[STOREMERGE:%.*]] = select i1 [[TOBOOL]], i32* @g, i32* null +; CHECK-NEXT: ret i32* [[STOREMERGE]] +; +entry: + %0 = load i32, i32* @g, align 4 + %tobool = icmp eq i32 %0, 0 + br i1 %tobool, label %exit, label %block1 + +block1: + br i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @g), label %exit, label %block2 + +block2: + br label %exit + +exit: + %storemerge = phi i32* [ select (i1 icmp eq (i64 urem (i64 2, i64 zext (i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @g) to i64)), i64 0), i32* null, i32* @g), %entry ],[ null, %block2 ], [ null, %block1 ] + ret i32* %storemerge +} + +define i32* @no_trap3() { +; CHECK-LABEL: @no_trap3( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @g, align 4 +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP0]], 0 +; CHECK-NEXT: ret i32* null +; +entry: + %0 = load i32, i32* @g, align 4 + %tobool = icmp eq i32 %0, 0 + br i1 %tobool, label %exit, label %block1 + +block1: + br i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @g), label %exit, label %block2 + +block2: + br label %exit + +exit: + %storemerge = phi i32* [ null, %entry ],[ null, %block2 ], [ select (i1 icmp eq (i64 add (i64 2, i64 zext (i1 icmp eq (i32* bitcast (i8* @b to i32*), i32* @g) to i64)), i64 0), i32* null, i32* @g), %block1 ] + ret i32* %storemerge +}