[llvm] r334019 - [InstCombine] Correct the cmp operand type used when canonicalizing abs/nabs

John Brawn via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 5 07:10:55 PDT 2018


Author: john.brawn
Date: Tue Jun  5 07:10:55 2018
New Revision: 334019

URL: http://llvm.org/viewvc/llvm-project?rev=334019&view=rev
Log:
[InstCombine] Correct the cmp operand type used when canonicalizing abs/nabs

When adjusting a cmp in order to canonicalize an abs/nabs select pattern we need
to use the type of the existing operand when creating a new operand not the
type of a select operand, as the two may be different.

This fixes PR37686.

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp
    llvm/trunk/test/Transforms/InstCombine/abs-1.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp?rev=334019&r1=334018&r2=334019&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineSelect.cpp Tue Jun  5 07:10:55 2018
@@ -818,7 +818,7 @@ static Instruction *canonicalizeAbsNabs(
 
   // Create the canonical compare.
   Cmp.setPredicate(ICmpInst::ICMP_SLT);
-  Cmp.setOperand(1, ConstantInt::getNullValue(LHS->getType()));
+  Cmp.setOperand(1, ConstantInt::getNullValue(Cmp.getOperand(0)->getType()));
 
   // If the select operands do not change, we're done.
   Value *TVal = Sel.getTrueValue();

Modified: llvm/trunk/test/Transforms/InstCombine/abs-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/abs-1.ll?rev=334019&r1=334018&r2=334019&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/abs-1.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/abs-1.ll Tue Jun  5 07:10:55 2018
@@ -101,6 +101,21 @@ define i8 @abs_canonical_4(i8 %x) {
   ret i8 %abs
 }
 
+define i32 @abs_canonical_5(i8 %x) {
+; CHECK-LABEL: @abs_canonical_5(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
+; CHECK-NEXT:    [[CONV:%.*]] = sext i8 [[X]] to i32
+; CHECK-NEXT:    [[NEG:%.*]] = sub nsw i32 0, [[CONV]]
+; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i32 [[NEG]], i32 [[CONV]]
+; CHECK-NEXT:    ret i32 [[ABS]]
+;
+  %cmp = icmp sgt i8 %x, 0
+  %conv = sext i8 %x to i32
+  %neg = sub i32 0, %conv
+  %abs = select i1 %cmp, i32 %conv, i32 %neg
+  ret i32 %abs
+}
+
 ; We have a canonical form of nabs to make CSE easier.
 
 define i8 @nabs_canonical_1(i8 %x) {
@@ -159,6 +174,21 @@ define i8 @nabs_canonical_4(i8 %x) {
   ret i8 %abs
 }
 
+define i32 @nabs_canonical_5(i8 %x) {
+; CHECK-LABEL: @nabs_canonical_5(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
+; CHECK-NEXT:    [[CONV:%.*]] = sext i8 [[X]] to i32
+; CHECK-NEXT:    [[NEG:%.*]] = sub nsw i32 0, [[CONV]]
+; CHECK-NEXT:    [[ABS:%.*]] = select i1 [[CMP]], i32 [[CONV]], i32 [[NEG]]
+; CHECK-NEXT:    ret i32 [[ABS]]
+;
+  %cmp = icmp sgt i8 %x, 0
+  %conv = sext i8 %x to i32
+  %neg = sub i32 0, %conv
+  %abs = select i1 %cmp, i32 %neg, i32 %conv
+  ret i32 %abs
+}
+
 ; The following 5 tests use a shift+add+xor to implement abs():
 ; B = ashr i8 A, 7  -- smear the sign bit.
 ; xor (add A, B), B -- add -1 and flip bits if negative




More information about the llvm-commits mailing list