From cd188e9665b3ff50d57a91b267bb6294ed646539 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 29 Nov 2009 02:57:29 +0000 Subject: [PATCH] add testcases for the foo_with_overflow op xforms added recently and fix bugs exposed by the tests. Testcases from Alastair Lynn! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@90056 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Scalar/InstructionCombining.cpp | 27 ++++--- test/Transforms/InstCombine/intrinsics.ll | 73 ++++++++++++++++++- 2 files changed, 85 insertions(+), 15 deletions(-) diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index ce471b398c5..d12ad815f5a 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -9934,9 +9934,9 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { // Create a simple add instruction, and insert it into the struct. Instruction *Add = BinaryOperator::CreateAdd(LHS, RHS, "", &CI); Worklist.Add(Add); - Constant *V[2]; - V[0] = UndefValue::get(LHS->getType()); - V[1] = ConstantInt::getTrue(*Context); + Constant *V[] = { + UndefValue::get(LHS->getType()), ConstantInt::getTrue(*Context) + }; Constant *Struct = ConstantStruct::get(*Context, V, 2, false); return InsertValueInst::Create(Struct, Add, 0); } @@ -9946,9 +9946,9 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { // Create a simple add instruction, and insert it into the struct. Instruction *Add = BinaryOperator::CreateNUWAdd(LHS, RHS, "", &CI); Worklist.Add(Add); - Constant *V[2]; - V[0] = UndefValue::get(LHS->getType()); - V[1] = ConstantInt::getFalse(*Context); + Constant *V[] = { + UndefValue::get(LHS->getType()), ConstantInt::getFalse(*Context) + }; Constant *Struct = ConstantStruct::get(*Context, V, 2, false); return InsertValueInst::Create(Struct, Add, 0); } @@ -9973,7 +9973,8 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { // X + 0 -> {X, false} if (RHS->isZero()) { Constant *V[] = { - UndefValue::get(II->getType()), ConstantInt::getFalse(*Context) + UndefValue::get(II->getOperand(0)->getType()), + ConstantInt::getFalse(*Context) }; Constant *Struct = ConstantStruct::get(*Context, V, 2, false); return InsertValueInst::Create(Struct, II->getOperand(1), 0); @@ -9992,7 +9993,8 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { // X - 0 -> {X, false} if (RHS->isZero()) { Constant *V[] = { - UndefValue::get(II->getType()), ConstantInt::getFalse(*Context) + UndefValue::get(II->getOperand(1)->getType()), + ConstantInt::getFalse(*Context) }; Constant *Struct = ConstantStruct::get(*Context, V, 2, false); return InsertValueInst::Create(Struct, II->getOperand(1), 0); @@ -10021,11 +10023,12 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { // X * 1 -> {X, false} if (RHSI->equalsInt(1)) { - Constant *V[2]; - V[0] = UndefValue::get(II->getType()); - V[1] = ConstantInt::getFalse(*Context); + Constant *V[] = { + UndefValue::get(II->getOperand(1)->getType()), + ConstantInt::getFalse(*Context) + }; Constant *Struct = ConstantStruct::get(*Context, V, 2, false); - return InsertValueInst::Create(Struct, II->getOperand(1), 1); + return InsertValueInst::Create(Struct, II->getOperand(1), 0); } } break; diff --git a/test/Transforms/InstCombine/intrinsics.ll b/test/Transforms/InstCombine/intrinsics.ll index 7abd3804013..fda4386e943 100644 --- a/test/Transforms/InstCombine/intrinsics.ll +++ b/test/Transforms/InstCombine/intrinsics.ll @@ -1,12 +1,79 @@ ; RUN: opt %s -instcombine -S | FileCheck %s -declare {i8, i1} @llvm.uadd.with.overflow.i8(i8, i8) +%overflow.result = type {i8, i1} + +declare %overflow.result @llvm.uadd.with.overflow.i8(i8, i8) +declare %overflow.result @llvm.umul.with.overflow.i8(i8, i8) define i8 @test1(i8 %A, i8 %B) { - %x = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 %A, i8 %B) - %y = extractvalue {i8, i1} %x, 0 + %x = call %overflow.result @llvm.uadd.with.overflow.i8(i8 %A, i8 %B) + %y = extractvalue %overflow.result %x, 0 ret i8 %y ; CHECK: @test1 ; CHECK-NEXT: %y = add i8 %A, %B ; CHECK-NEXT: ret i8 %y } + +define i8 @test2(i8 %A, i8 %B, i1* %overflowPtr) { + %and.A = and i8 %A, 127 + %and.B = and i8 %B, 127 + %x = call %overflow.result @llvm.uadd.with.overflow.i8(i8 %and.A, i8 %and.B) + %y = extractvalue %overflow.result %x, 0 + %z = extractvalue %overflow.result %x, 1 + store i1 %z, i1* %overflowPtr + ret i8 %y +; CHECK: @test2 +; CHECK-NEXT: %and.A = and i8 %A, 127 +; CHECK-NEXT: %and.B = and i8 %B, 127 +; CHECK-NEXT: %1 = add nuw i8 %and.A, %and.B +; CHECK-NEXT: store i1 false, i1* %overflowPtr +; CHECK-NEXT: ret i8 %1 +} + +define i8 @test3(i8 %A, i8 %B, i1* %overflowPtr) { + %or.A = or i8 %A, -128 + %or.B = or i8 %B, -128 + %x = call %overflow.result @llvm.uadd.with.overflow.i8(i8 %or.A, i8 %or.B) + %y = extractvalue %overflow.result %x, 0 + %z = extractvalue %overflow.result %x, 1 + store i1 %z, i1* %overflowPtr + ret i8 %y +; CHECK: @test3 +; CHECK-NEXT: %or.A = or i8 %A, -128 +; CHECK-NEXT: %or.B = or i8 %B, -128 +; CHECK-NEXT: %1 = add i8 %or.A, %or.B +; CHECK-NEXT: store i1 true, i1* %overflowPtr +; CHECK-NEXT: ret i8 %1 +} + +define i8 @test4(i8 %A, i1* %overflowPtr) { + %x = call %overflow.result @llvm.uadd.with.overflow.i8(i8 undef, i8 %A) + %y = extractvalue %overflow.result %x, 0 + %z = extractvalue %overflow.result %x, 1 + store i1 %z, i1* %overflowPtr + ret i8 %y +; CHECK: @test4 +; CHECK-NEXT: ret i8 undef +} + +define i8 @test5(i8 %A, i1* %overflowPtr) { + %x = call %overflow.result @llvm.umul.with.overflow.i8(i8 0, i8 %A) + %y = extractvalue %overflow.result %x, 0 + %z = extractvalue %overflow.result %x, 1 + store i1 %z, i1* %overflowPtr + ret i8 %y +; CHECK: @test5 +; CHECK-NEXT: store i1 false, i1* %overflowPtr +; CHECK-NEXT: ret i8 0 +} + +define i8 @test6(i8 %A, i1* %overflowPtr) { + %x = call %overflow.result @llvm.umul.with.overflow.i8(i8 1, i8 %A) + %y = extractvalue %overflow.result %x, 0 + %z = extractvalue %overflow.result %x, 1 + store i1 %z, i1* %overflowPtr + ret i8 %y +; CHECK: @test6 +; CHECK-NEXT: store i1 false, i1* %overflowPtr +; CHECK-NEXT: ret i8 %A +}