llvm.org GIT mirror
Transform -X/C to X/-C, implementing a README.txt entry. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78812 91177308-0d34-0410-b5e6-96231b3b80d8 Dan Gohman 10 years ago
3 changed file(s) with 28 addition(s) and 10 deletion(s).
 1110 1110 1111 1111 //===---------------------------------------------------------------------===// 1112 1112 1113 We would like to do the following transform in the instcombiner: 1114 1115 -X/C -> X/-C 1116 1117 However, this isn't valid if (-X) overflows. We can implement this when we 1118 have the concept of a "C signed subtraction" operator that which is undefined 1119 on overflow. 1120 1121 //===---------------------------------------------------------------------===// 1122 1123 1113 This was noticed in the entryblock for grokdeclarator in 403.gcc: 1124 1114 1125 1115 %tmp = icmp eq i32 %decl_context, 4
 3076 3076 RHS->getValue().exactLogBase2()); 3077 3077 return BinaryOperator::CreateAShr(Op0, ShAmt, I.getName()); 3078 3078 } 3079 3080 // -X/C --> X/-C provided the negation doesn't overflow. 3081 if (SubOperator *Sub = dyn_cast(Op0)) 3082 if (isa(Sub->getOperand(0)) && 3083 cast(Sub->getOperand(0))->isNullValue() && 3084 Sub->hasNoSignedOverflow()) 3085 return BinaryOperator::CreateSDiv(Sub->getOperand(1), 3086 ConstantExpr::getNeg(RHS)); 3079 3087 } 3080 3088 3081 3089 // If the sign bits of both operands are zero (i.e. we can prove they are
 0 ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | FileCheck %s 1 2 ; CHECK: define i32 @foo 3 ; %y = sub i32 0, %x 4 ; %z = sdiv i32 %y, 337 5 ; ret i32 %y 6 define i32 @foo(i32 %x) { 7 %y = sub i32 0, %x 8 %z = sdiv i32 %y, 337 9 ret i32 %y 10 } 11 12 ; CHECK: define i32 @bar 13 ; %y = sdiv i32 %x, -337 14 ; ret i32 %y 15 define i32 @bar(i32 %x) { 16 %y = sub nsw i32 0, %x 17 %z = sdiv i32 %y, 337 18 ret i32 %y 19 }